我正在开发一个应用程序,其中大量的线程需要迭代一组字符串值,并尝试将其自己的数据与列表中的可用数据进行匹配 .
我正在寻找以下用例:
-
Vector初始化为几个std :: string类型的元素 . (可以说对象名是strList) . strList将在应用程序启动时初始化 .
-
所有线程将遍历strList以查看它的值是否与strList的至少一个元素匹配 .
-
没有线程会尝试修改strList,它将严格用作只读对象 .
那么请告诉我并发读取是否对矢量对象是线程安全的 . 我使用的是RHEL 6,gcc版本是4.5.x
3 回答
YES 对于你提到的场景,它是完全线程安全的 .
实际上,STL并不是一种正确的引用方式 .
这是 C++ Standard Library .
C 03标准根本不讨论并发性,因此并发性方面被省略为编译器的实现细节 . 因此,编译器附带的文档是应该查找与并发相关的答案的地方 .
大多数STL实现都是 not 线程安全的 .
但是对于来自多个线程的同一对象的并发读取,大多数STL实现确实是线程安全的 .
References:
MSDN 说:
The Dinkumware STL-Documentation 说:
GCC Documentation 说:
我们目前使用线程安全的 SGI STL 定义,其中指出:
所以从上面可以看出,GCC中的线程安全是从多个线程并发读取同一个对象 .
注意:GCC的标准库是SGI的STL代码的衍生物 .
为此,在C 0x FDIS(n3290)中有一个特别的提及 .
整段是有意义的,但更具体的是:
意味着您可以安全地在
std::vector<T>
上调用cbegin
和cend
. 以及在std::string
上调用operator==
或operator<
.意味着仅仅迭代容器不应该以任何方式修改所述容器 .
虽然3 /尽管如此,但似乎有全局对象的空间,因为迭代器修改某种共享的寄存器对象,在这些对象中它们将自己与容器相关联(STL调试功能) . 我没理解:
除此以外 .
无论如何,标准保证迭代
vector
将是安全的...但是在实际读取对象时(这些是你自己的)不能保证 . 在这种情况下,这包括在内,因为上面介绍了std::string
.EDIT: 正如David Hammen所说,该标准尚未完全实施 . 许多编译器已经提供了上述保证,即使之前的标准从未提及线程 . MSVC,gcc,clang,icc,comeau等......从Als的回答中可以看出,所有大牌都应该已经提供了这种保证 .
除了关于数据竞争规避的通用规则之外,在[container.requirements.dataraces]中标准说
所以,即使你只是在不安全的情况下调用非const
begin()
/end()
等等 .