首先,对于一些帖子和评论,文档何时可靠?
其次,这个答案更多的是针对一般问题而不是 OP 的具体问题。
我在理论上同意 MrFox 的观点,因为这一切都归结为两个问题:
- List 类是作为平面数组实现的吗?
如果是,那么:
- 写指令可以在写过程中被抢占吗>
我相信情况并非如此——完整的写入将在任何东西可以读取该 DWORD 或其他任何内容之前发生。换句话说,永远不会发生我写一个 DWORD 的四个字节中的两个,然后你读取新值的 1/2 和旧值的 1/2。
因此,如果您通过为某个指针提供偏移量来索引数组,则可以在没有线程锁定的情况下安全地读取。如果 List 不仅仅是简单的指针数学运算,那么它就不是线程安全的。
如果 List 没有使用平面数组,我想你现在应该已经看到它崩溃了。
我自己的经验是,通过索引从列表中读取单个项目而无需线程锁定是安全的。不过,这一切都只是恕我直言,所以要物有所值。
最坏的情况,比如如果你需要遍历列表,最好的办法是:
- 锁定列表
- 创建一个相同大小的数组
- 使用 CopyTo() 将 List 复制到数组
- 解锁列表
- 然后遍历数组而不是列表。
在(无论您如何称呼 .net)C++ 中:
List<Object^>^ objects = gcnew List<Object^>^();
// in some reader thread:
Monitor::Enter(objects);
array<Object^>^ objs = gcnew array<Object^>(objects->Count);
objects->CopyTo(objs);
Monitor::Exit(objects);
// use objs array
即使分配了内存,这也比锁定 List 并在解锁之前遍历整个内容要快。
不过请注意:如果您想要一个快速的系统,线程锁定是您最大的敌人。请改用ZeroMQ。我可以根据经验说话,基于消息的同步是正确的方法。