可能的重复项:
是否需要在多线程环境中保护对 STL 容器的读取访问?
如果某个线程读取 :set 或 :map 当另一个线程写入此集合或映射时,会发生什么?例外?
现在我使用读写锁,但我想删除锁,因为写入操作不常见,读取操作经常。
竞争条件将会发生:根据 CPU 对所做事情的排序,您每次都会收到不同的结果。如果迭代器无效(例如,通过删除一个线程中的项目,而另一个线程有一个迭代器指向现在无效的内存),然后在另一个线程中使用,您将获得未定义的行为,因此要警惕死去的婴儿、粘土傀儡和闹鬼,以及更可能的段错误、延迟段错误, 和运行时崩溃。
C++11 引入了mutex
和其他线程功能:如有必要,请使用这些工具保护您的读写。
标准容器不是线程安全的,并且它们没有被指定为 Java 意义上的"快速失败"迭代器。因此,不受保护的并发访问至少会出现两点问题:
- 容器上的数据争用,这是未定义的行为 一个线程使迭代器
- 失效,然后另一个线程使用等值迭代器。这也是未定义的行为,但它不一定是数据竞赛,并且也是单线程程序中的错误。当它们在不同的线程中使用时,更容易忘记同一容器上的多个迭代器。
有人可能会说,C++哲学是"快速成功",不要介意程序员失败时会发生什么;-)。因此,对于许多用户来说,没有多余的内置锁。相反,这是你的问题 - 你宁愿不高兴锁正在减慢这个程序,而不是不高兴他们正在减慢这个程序和你曾经编写的所有其他使用set
的程序,即使集合没有同时访问。
写入操作不常见,读取操作不常见。
这正是读写器锁应该表现良好的情况。改善情况的唯一方法是将写入操作从"不经常"减少到"从不",而这大概是做不到的。
互斥锁,锁....BRRR尝试使用自由锁定容器。例如英特尔"线程构建模块"又名TBBhttp://threadingbuildingblocks.org/files/documentation/a00130.html