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:不过,如果您只从 vector 中读取,则不需要线程安全,因为没有数据争用,一切都很好。
最好不要将 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。
此外,从不同的元素读取 from/writing 与 reading/writing 是相互线程安全的,并且读取 from/writing 与其他 [=15] 元素是相互线程安全的=] 容器上的操作(以及其他被上述规则 视为 const 的操作)。
std::vector
保证在通过 const
方法或通过 视为常量的方法调用自身时,它只会调用 类 上的 const
方法 根据上述规则。如果您的对象的 const
方法不能实现相互线程安全,那么一切都将失败。
有关详细信息,请参阅 Does const
mean thread safe。
如果我正在访问 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:不过,如果您只从 vector 中读取,则不需要线程安全,因为没有数据争用,一切都很好。
最好不要将 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。
此外,从不同的元素读取 from/writing 与 reading/writing 是相互线程安全的,并且读取 from/writing 与其他 [=15] 元素是相互线程安全的=] 容器上的操作(以及其他被上述规则 视为 const 的操作)。
std::vector
保证在通过 const
方法或通过 视为常量的方法调用自身时,它只会调用 类 上的 const
方法 根据上述规则。如果您的对象的 const
方法不能实现相互线程安全,那么一切都将失败。
有关详细信息,请参阅 Does const
mean thread safe。