首先,一些帖子和评论,因为什么时候文件可靠?
其次,这个答案更多的是一般性问题,而不是OP的具体细节。
我MrFox同意理论,因为这一切都归结为两个问题:
- 是List类实现为平板阵列?
如果是的话:
- 可以写入指令在写>
中间被抢占,我相信这是不是这样的 - 全写会发生在任何事情都可以读取DWORD或任何东西之前。换句话说,我永远不会发生这样的情况:我写了一个DWORD的四个字节中的两个字节,然后读取1/2的新值和1/2的旧值。
因此,如果您通过为某个指针提供偏移量来索引数组,则可以安全地读取,而无需线程锁定。如果List不仅仅是简单的指针数学,那么它就不是线程安全的。
如果List没有使用平面数组,我认为您现在已经看到它崩溃了。
我自己的经验是,通过索引从列表中读取单个项目是安全的,无需线程锁定。这只是恕我直言,但所以要拿它的价值。
最坏的情况,例如,如果您需要在列表中迭代,做的最好的事情是:
- 锁定列表
- 创建数组大小相同
- 使用CopyTo从()将列表复制到阵列
- 解锁列表
- 然后遍历数组而不是列表。
中(无论你怎么称呼的.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
即使在内存分配,这将是比锁定列表和解锁前通过整个事情迭代更快。
尽管如此:如果你想要一个快速的系统,线程锁定是你最大的敌人。改为使用ZeroMQ。我可以从经验中发言,基于消息的同步是正确的路线。
来源
2012-01-17 03:02:36
Jin
列表的线程安全性与列表中的对象字段的线程安全性无关。即使您将实际列表设置为线程安全,您所描述的问题仍然存在。 –
@Brois是的,你是对的,他应该锁定每一件可以从多线程更新的东西。 –
@Chuu有没有反馈? –