C ++ std容器的线程安全性

时间:2013-09-06 11:53:48

标签: c++ multithreading stl c++03

我在这里阅读了很多帖子,问题是C ++的标准容器(如“list”或“map”是否是线程安全的,并且所有人都说它不是一般的。并行读取应该没问题,但是并行写入或并行读写可能会导致问题。

现在我发现在www.cplusplus.com,在大多数操作期间访问或修改列表是安全的。

一些例子:

map::find

访问容器(const和非const版本都不会修改容器)。 没有访问映射值:同时访问或修改元素是安全的。

map::insert

容器已修改。 同时访问现有元素是安全的,尽管容器中的迭代范围不是。

我是否想念cplusplus.com或者我还有什么关于std容器中线程安全的知识。

提前致谢!

PS:我要的是C ++ 03而不是C ++ 11

4 个答案:

答案 0 :(得分:12)

  

并行读取应该没问题,但并行写入或并行读写可能会导致问题。

这是对的。这是对C ++中对象的非同步访问提供的一般保证。这些“问题”被正式称为数据竞赛

  

现在我发现在www.cplusplus.com上,在大多数操作过程中访问或修改列表是安全的。

不,容器不提供并发读取的基本保证。如果一个线程访问它而另一个线程修改它,则会有数据竞争。但是,对于某些容器,在容器本身被修改时,有时可以安全地访问容器的元素

第一个例子是find 修改容器或访问元素 values (只有键),所以如果其他线程正在访问它是安全的它,或修改(不同)值而不修改容器本身。

第二个例子说你可以安全地访问现有元素(使用该元素的引用或迭代器),因为插入元素不会干扰现有元素。

  

我要的是C ++而不是C ++ 11

目前,C ++ C ++ 11。如果你问的是该语言的历史版本,他们对线程没有什么可说的,所以问题一般不负责,只针对特定的实现和线程框架。

答案 1 :(得分:5)

听起来很对。

请注意,如果修改实际值,则从多个线程访问map中的值也需要受到保护。如果你知道两个线程更新不同的条目(我不是指插入/删除),那么它是安全的。

答案 2 :(得分:3)

在C ++ 11之前,标准中没有“线程”的概念。因此,在C ++ 03的上下文中,容器是否是线程安全的问题是没有意义的。

答案 3 :(得分:0)

正如Marcin指出的那样,C ++ 03没有线程的概念;因此,即使在完全完成写入后在两个线程中并发读取,也不能假设任何线程安全操作。

想想这个案例: 在t = 0时,你创建一个线程,让我们调用A. 在t = 10秒时,线程B(在创建线程A之前存在)写入容器。 在t = 1小时,线程A和B都尝试通过第三方库(例如pthread)读取容器而没有任何同步。

C ++ 03仅保证线程B将看到正确的值。但是不能保证线程A会看到正确的值,因为C ++ 03期望每个程序都是单线程,因此C ++ 03规范只能保证在编程顺序中可见的事件序列(如同在1中一样)线程)。