C++ stl向量并发读取线程安全吗?

C++ stl向量并发读取线程安全吗?,c++,concurrency,stl,thread-safety,language-lawyer,C++,Concurrency,Stl,Thread Safety,Language Lawyer,我正在开发一个应用程序,在这个应用程序中,大量线程将迭代字符串值集,并尝试将其自身的数据与列表中可用的数据相匹配 我正在寻找以下用例: 向量是用std::string类型的几个元素初始化的。(假设对象名为strList)。strList将在应用程序启动时初始化 所有线程都将迭代strList,以查看它的值是否与strList的至少一个元素匹配 没有线程会试图修改strList,它将严格用作只读对象 所以,你们能告诉我在向量对象上并发读取是否是线程安全的吗。我使用的是RHEL 6,gcc版本是4.

我正在开发一个应用程序,在这个应用程序中,大量线程将迭代字符串值集,并尝试将其自身的数据与列表中可用的数据相匹配

我正在寻找以下用例:

  • 向量是用std::string类型的几个元素初始化的。(假设对象名为strList)。strList将在应用程序启动时初始化
  • 所有线程都将迭代strList,以查看它的值是否与strList的至少一个元素匹配
  • 没有线程会试图修改strList,它将严格用作只读对象

  • 所以,你们能告诉我在向量对象上并发读取是否是线程安全的吗。我使用的是RHEL 6,gcc版本是4.5.x

    对于您提到的场景,它是完全线程安全的


    实际上,STL并不是一种正确的引用方式。
    它是

    C++03标准根本没有谈到并发性,因此,对于编译器来说,并发性方面作为一个实现细节被忽略了。因此,编译器附带的文档是我们应该寻找与并发性相关的答案的地方

    大多数STL实现本身不是线程安全的。
    但对于从多个线程并发读取同一对象,STL的大多数实现确实是线程安全的

    参考文献:

    说:

    单个对象对于从多个线程读取是线程安全的。例如,给定一个对象A,同时从线程1和线程2读取A是安全的

    Dinkumware STL文档说明:

    多个线程可以安全地读取同一个容器对象。(容器对象中存在不受保护的可变子对象。)

    说:

    我们目前使用线程安全的定义,其中规定:

    STL的SGI实现只有在同时访问不同容器是安全的,同时读取访问共享容器是安全的情况下才是线程安全的如果多个线程访问单个容器,并且至少有一个线程可能会写入,则用户负责确保容器访问期间线程之间的互斥。

    因此,从上面可以看出,在GCC中,从多个线程并发读取同一对象是线程安全的


    注意:GCC的标准库是SGI的STL代码的派生版本。

    在C++0x FDI(n3290)中对此有特别提及

    §17.6.5.9数据竞争避免

    整段内容令人感兴趣,但更具体地说:

    3,A/C++标准库函数不直接或间接地修改对象(1.10),而不是通过当前线程的线程访问,除非对象直接或间接地通过函数的非const参数访问,包括这个。


    意味着您可以在
    std::vector
    上安全地调用
    cbegin
    cend
    。除了在[container.requirements.dataraces]中调用关于避免数据竞争的一般规则外,还可以调用
    operator==
    operator

    P>>1 -为了避免数据竞争(17.5.9),实现应考虑以下功能:“代码>开始/代码>,<代码>结束/代码>,<代码> RCAD/<代码>,<代码> Read <代码>,<代码>前面<代码>,<代码>返回< /代码>,<代码>数据< /代码>,<代码>查找< /代码>,<代码>低级绑定< /代码>,<代码>上限> <代码>
    equal_range
    at
    ,并且,除了在关联或无序关联容器中,
    运算符[]


    因此,即使您调用非常量
    begin()
    /
    end()
    等,只要您实际上不修改任何内容,它也是安全的

    是的,子弹3没问题,没错。我已经阅读了MSDN。但我在RHEL上使用gcc,我必须对并发读取中的线程安全性有200%的把握。您指的是一个标准,尽管(最终!)得到了批准和发布,但据我所知,任何编译器供应商尚未完全实现该标准。当没有人实施某个标准时,如果说某个人可以依靠某个标准,那可能还为时过早。@David:嗯,没错。我要澄清的是,事实上,这只是设置了所有质量实现已经完成的内容。