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