C++11 容器线程安全

C++11 容器线程安全,c++11,concurrency,stl,C++11,Concurrency,Stl,我了解此处列出的容器线程安全主题: 但我想知道:我可以在不阻塞(互斥)的情况下同时使用非常量成员函数和常量成员函数吗? 更具体地说: 我可以同时使用std::vector::push_back和std::vector::size吗 我可以同时使用std::set::insert和std::set::size吗 这通常没有实际意义,但我不需要使用大小的精确结果,我只需要在调用时得到一个有效的结果 另外,我的疑问来自于这里:他们说的std::set::insert在哪里 同时访问现有元素是安全的

我了解此处列出的容器线程安全主题:

但我想知道:我可以在不阻塞(互斥)的情况下同时使用非常量成员函数和常量成员函数吗? 更具体地说:

  • 我可以同时使用std::vector::push_back和std::vector::size吗
  • 我可以同时使用std::set::insert和std::set::size吗

  • 这通常没有实际意义,但我不需要使用大小的精确结果,我只需要在调用时得到一个有效的结果

    另外,我的疑问来自于这里:他们说的std::set::insert在哪里

    同时访问现有元素是安全的


    因此,获取容器的大小也可能是安全的。

    stl容器的主要线程安全规则是,如果多个工作线程正在访问一个共享容器,并且其中至少一个线程是非常量的,那么线程应该同步。如果不放置任何同步,则这将是未定义的行为

    如果您查看C++代码引用,请参阅代码> STD::vector:siz()/<代码>,它表示:

    数据竞赛

    已访问容器。未访问包含的元素: 同时访问或修改它们是安全的


    如前所述,调用
    .size()
    时将访问
    向量
    容器,此访问不允许您同时在
    向量
    上调用非常量方法。如果通过调用
    .size()
    获得
    向量的大小时
    将元素推回
    向量,则程序的行为将是未定义的。

    stl容器的主线程安全规则是,如果多个工作线程正在访问共享容器,其中至少有一个线程是非常量的,那么线程应该同步。如果不放置任何同步,则这将是未定义的行为

    如果您查看C++代码引用,请参阅代码> STD::vector:siz()/<代码>,它表示:

    数据竞赛

    已访问容器。未访问包含的元素: 同时访问或修改它们是安全的


    如前所述,调用
    .size()
    时将访问
    向量
    容器,此访问不允许您同时在
    向量
    上调用非常量方法。如果通过调用
    .size()
    获得
    向量的大小时,将
    元素推回
    向量,则程序的行为将是未定义的。

    谢谢您的回答。但我认为你的说法并非绝对正确,因为我们可能会写一个“向量”,改变它的元素,同时使用“大小”作为例子。因此,我假设您的意思是“如果有多个工作线程正在访问一个共享容器,并且其中至少有一个正在修改所提到的容器本身(可能是写入容器的副作用),那么线程应该同步”或者我不理解您的语句。@cyrax我的语句只有一句话:如果两个线程正在访问同一个容器,其中一个正在写入容器,那么您的线程应该同步。否则,程序的行为是未定义的。您正在编写相同的程序,因此它无法解释任何内容。在我的示例中,一个线程正在使用
    运算符[]
    写入向量,另一个线程正在调用常量成员函数
    size()
    ,但它们不需要按照容器线程安全主题中的说明进行同步。“你同意还是不同意?”cyrax为我迟来的回复感到抱歉。是的,你说得对。在这种情况下,根据标准,不需要同步,因为这里将
    操作符[]
    视为常量。我已经更新了我的答案。谢谢你的回答。但我认为你的说法并非绝对正确,因为我们可能会写一个“向量”,改变它的元素,同时使用“大小”作为例子。因此,我假设您的意思是“如果有多个工作线程正在访问一个共享容器,并且其中至少有一个正在修改所提到的容器本身(可能是写入容器的副作用),那么线程应该同步”或者我不理解您的语句。@cyrax我的语句只有一句话:如果两个线程正在访问同一个容器,其中一个正在写入容器,那么您的线程应该同步。否则,程序的行为是未定义的。您正在编写相同的程序,因此它无法解释任何内容。在我的示例中,一个线程正在使用
    运算符[]
    写入向量,另一个线程正在调用常量成员函数
    size()
    ,但它们不需要按照容器线程安全主题中的说明进行同步。“你同意还是不同意?”cyrax为我迟来的回复感到抱歉。是的,你说得对。在这种情况下,根据标准,不需要同步,因为这里将
    操作符[]
    视为常量。我已经更新了我的答案,“我不需要一个我将使用的精确的大小结果,我只需要在调用它的时候得到一个有效的结果”——为了实现这一点,大小需要是内部原子的,而不是。这与一个线程写入另一个线程读取的任何普通变量相同。“我不需要使用大小的精确结果,我只需要在调用时使用有效的结果”-要使其工作,大小需要是内部原子的,而不是。这与一个线程写入另一个线程读取的任何普通变量相同。