我很难找到关于此事的最新信息。
C++11版本的STL容器是否保证了一定程度的线程安全?
考虑到性能问题,我不认为它们会有,但另一方面,这就是我们拥有 std::vector::operator[]
和 std::vector::at
的原因。
我很难找到关于此事的最新信息。
C++11版本的STL容器是否保证了一定程度的线程安全?
考虑到性能问题,我不认为它们会有,但另一方面,这就是我们拥有 std::vector::operator[]
和 std::vector::at
的原因。
由于现有的回答没有涵盖它(只有一个评论),因此我将提到当前C ++标准规范的23.2.2 [container.requirements.dataraces],其中说:
当在同一个序列中不同元素的包含对象的内容被同时修改时(除了
vector<bool>
),实现必须避免数据竞争。
也就是说,安全地访问同一容器的不同元素是安全的,例如,您可以拥有一个全局的std::vector<std::future<int>>
,其中包含十个元素,并且有十个线程,每个线程都写入向量的不同元素。
除此之外,与标准库的其余部分相同的规则适用于容器(请参见17.6.5.9 [res.on.data.races]),正如Mr.C64的回答所述,另外[container.requirements.dataraces]列出了一些容器的非const成员函数,可以安全地调用它们,因为它们仅返回对元素的非const引用,它们实际上不会修改任何东西(通常任何非const成员函数都必须被认为是修改。)
我认为STL容器提供以下基本的线程安全保证:
同一对象的同时读取是可以的。
不同对象的同时读/写操作是可以的。
但如果你想进行其他操作,例如对同一个对象进行同时写入,那么就必须使用某种形式的自定义同步(例如关键区域)。
myvec[0] = 0
和myvec[1]
是可以的吗?如果“对象”是容器,那么这就是对同一对象的读写操作,但如果“对象”是元素,则不是。您还可以将容器想象成一个伸展树,其中对容器的同时读取是不允许的,但是如果有保证同时读取是可以的,那么std::map
不能被实现为在这方面不安全的伸展树。 - Steve Jessopmyvec[1]
操作时,myvec[0] = 0
可能会出现问题。对于顺序容器的 operator[]
操作必须避免数据竞争([container.requirements.dataraces]/1)。但这并不适用于无序和关联式容器。 - avakar不要使用STL容器,而是尝试使用PPL或Intel TBB进行线程安全容器操作。
正如其他人所指出的那样,它们具有通常的“多读线程安全性”,但这甚至在C++11之前就已经存在了。当然,这并不意味着单个写入者多个读取者。它意味着没有写入者。 :)