C++中向量和列表的非写入成员函数的线程安全性
Thread safety of the non-write member functions of vectors and lists in C++
如果我正在访问 std::vector 或 std::list 的成员函数,它是线程安全的吗?
例:
struct ABC
{
...
}
std::vector<ABC> vecofAbc;
以下操作是否是线程安全的,因为它们只是读取?
vecofAbc.at(1) ;
ABC::iterator iter = vecofAbc.end();
ABC::iterator iter = vecofAbc.begin();
同样,上面的 std::list 线程成员函数是否安全?
我知道 push_back(( 在写入时不会是线程安全的。
读取操作不是线程安全的。如果在执行读取操作时修改了容器,则存在数据争用,并且行为未定义。
读取操作本身不会创建竞争编码,因此多个读取不需要彼此同步 - 只需与修改相关。
读取是线程安全的,只要没有并行写入,就不需要同步机制。
当一个方法不受同时读取或写入相同数据的其他线程的影响时,它被称为线程安全的。因此,您只阅读的事实实际上无关紧要。您提到的方法不是线程安全的,因为如果有第二个线程同时修改向量,您将进行数据竞争。
PS:尽管如此,如果您只从向量中读取,则不需要线程安全,因为没有数据竞争,一切都很好。
最好不要将线程C++安全视为单个操作的属性,而是多个操作相对于彼此的属性。
vecofAbc.at(1) ;
ABC::iterator iter = vecofAbc.end();
ABC::iterator iter = vecofAbc.begin();
其中每个都是相互线程安全的。 它们可以发生在单独的线程中,不涉及数据争用。
有些操作与上述操作不相互线程安全。 这些包括
vecofAbc.push_back(some_abc);
vecofAbc.reserve(10000);
另请注意
vecofAbc[0] = some_abc;
与 的相互线程安全
vecofAbc.at(1);
或
vecofAbc[1] = some_abc;
该规则是容器上任意数量的const
操作都是相互线程安全的,并且就此规则而言,.begin()
、end()
和许多其他操作(不会改变容器布局(被视为const。
此外,从元素读取/写入元素与从不同元素读取/写入元素是相互线程安全的,并且从/写入元素与容器上的其他const
操作(以及上述规则视为const的其他操作(是相互线程安全的。
std::vector
保证它只会在通过const
方法或通过上述规则下被视为 const的方法调用类const
方法时调用类。 如果对象的const
方法无法相互线程安全,则所有赌注都将关闭。
有关更多详细信息,请参阅const
是否意味着线程安全。
如果您可以保证只有对此向量的读取访问权限,那么是的,从多个线程执行此操作是安全的。只有当线程更改某些内容时,才会出现问题。
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 将公共但非静态的成员函数与ALGLIB集成
- 使用指向成员的指针将成员函数作为参数传递
- 将重载的成员函数传递给函数模板
- 我不小心调用了一个没有自己类对象的成员函数.但这是怎么回事呢
- 如何在C++中使用非静态成员函数作为回调函数
- C++错误C2600:无法定义编译器生成的特殊成员函数(必须首先在类中声明)
- 关联容器的下界复杂性:成员函数与非成员函数
- 在 C++ 中用派生类型重写成员函数
- 链表的泛型函数remove()与成员函数remove)
- 如何将lambda作为模板类的成员函数参数
- constexpr构造函数需要常量成员函数时出现问题
- 将自由函数绑定为类成员函数
- 区分非成员函数和头文件中的成员函数
- 如何从子成员函数修改父公共成员变量
- 保留对其他类的成员函数的引用
- 在运算符重载定义中使用成员函数(const错误)
- 内联如何影响模块接口中的成员函数
- 将成员函数指针作为参数传递给模板方法