1

可能重复:
我是否需要在多线程环境中保护对 STL 容器的读取访问?

如果某个线程读取 :set 或 :map 而另一个线程写入该 set 或 map,会发生什么?例外?

现在我使用读写锁,但我想删除锁,因为写操作不经常,读操作很频繁。

4

3 回答 3

4

竞态条件会发生:根据 CPU 所做的事情的顺序,您每次都会收到不同的结果。如果一个迭代器失效(例如,删除一个线程中的一个项目,而另一个线程有一个迭代器指向现在无效的内存)然后在另一个线程中使用,你将得到未定义的行为,所以要小心死婴儿,粘土golems 和 haunts,以及更可能的段错误、延迟段错误和运行时崩溃。

C++11 引入了mutex其他线程工具:如果必须,请使用这些工具保护您的读写。

于 2012-08-12T14:25:04.703 回答
0

mutexs,locks.... brrr 尝试使用免费的锁容器。例如英特尔“线程构建块”又名 TBB http://threadingbuildingblocks.org/files/documentation/a00130.html

于 2012-08-12T15:40:55.010 回答
0

标准容器不是线程安全的,并且没有指定它们具有 Java 意义上的“快速失败”迭代器。因此,无保护的并发访问至少有两件事会出错:

  1. 容器上的数据竞争,这是未定义的行为
  2. 一个线程使迭代器无效,随后另一个线程使用等值迭代器。这也是未定义的行为,但不一定是数据竞争,也可能是单线程程序中的错误。当它们在不同线程中使用时,在同一个容器上丢失多个迭代器会更容易一些。

有人可能会说 C++ 的哲学是“快速成功”,不要介意程序员失败时会发生什么;-)。因此,没有内置锁对许多用户来说是多余的。相反,这是你的问题——你宁愿不高兴锁正在减慢这个程序,而不是不高兴它们减慢了这个程序和你曾经写过的所有其他程序set,即使没有同时访问该集合。 .

写操作不经常,读操作非常频繁。

这正是读写器锁应该表现良好的情况。改善情况的唯一方法是,如果您可以将写操作从“不经常”减少到“从不”,这可能是您做不到的。

于 2012-08-12T15:42:23.817 回答