2012-08-12 78 views
1

可能重复:
Do I need to protect read access to an STL container in a multithreading environment?线程安全设置

如果某个线程读取:设置或:地图时另一个线程写入该组或地图,会发生什么?例外?

现在我用读写锁,但我想删除锁定,因为writining操作并不频繁,经常阅读操作。

+1

标准容器不是线程安全的。 – Xeo 2012-08-12 14:21:30

+0

@Xeo,所以会当一个线程读取容器时,另一个写它会怎么样呢?例外? – RomanKarpuk 2012-08-12 14:23:48

+3

@RomanKarpuk未定义的行为! – juanchopanza 2012-08-12 14:41:25

回答

4

比赛条件会发生:根据所做的事情CPU的订货,你们每个人都及时收到不同的结果。如果一个迭代器失效(例如通过删除在一个线程和其他线程指向,现在无效的内存迭代的项目)中的其他线程使用,然后,你会得到不确定的行为,所以要谨慎死婴,粘土傀儡,并常去的地方,与更多的可能就是内存设计缺陷,延迟内存设计缺陷和运行时崩溃一起。

C++ 11引入mutex和其他线程设施:保护您的读取和如果你必须写这些。

+0

“时,map/set操作符可能会改变结构”你会得到一个段错误“ - 你可能会遇到段错误。如果被无效化的迭代器指向的节点已经被释放并重新分配给别的东西,你可能会得到一个不太明显的错误。 – 2012-08-12 15:27:24

+0

最糟糕的bug的孩子不是段错误,而是似乎在工作流程中起作用并使后者崩溃的错误。在发生错误时在segfaults中感谢你。 – 2012-08-12 16:13:45

+0

@Loki:我的错误行为比之后在工作流中崩溃的情况更糟糕。例如,不会崩溃,但会导致程序的某些完全不相关的部分产生错误的答案。但我完全同意,越早越明显,越野车程序做错了,越好越好。因此,出现错误的段错误是非常好的。 – 2012-08-12 17:55:24

0

标准集装箱不是线程安全的,他们都没有指定具有Java中的“快速失败”迭代器。因此,至少有两件事情可以去错未受保护的并发访问:

  1. 的容器,这是不确定的行为
  2. 一个线程无效迭代器和后另一个线程上的数据争用的等值迭代器。这也是不确定的行为,但它不一定是一个数据的比赛,并会在一个单线程程序中的错误了。这只是简单一点,当他们在不同的线程已经习惯了失去跟踪多个迭代器相同的容器上。

有人可能会说C++的理念是“快速成功”,而不必介意程序员失败时会发生什么;-)。因此,没有内置的锁对于许多用户来说是冗余的。相反,它是你的问题 - 你宁愿不开心的是,锁放缓这一计划,比不快乐的,他们正在放慢这个程序,你写过所有其他程序使用set,即使置不同时访问的

写操作并不频繁,经常阅读操作。

这正是读写器锁定应该表现良好的情况。你可以改善你的情况的唯一方法是,如果你可以在“不经常”降低写入操作为“从不”,想必你不能哪些。如果它们是由一个线程修改