简体   繁体   English

默认情况下,std :: vector线程安全且并发吗? 为什么或者为什么不?

[英]Is std::vector thread-safe and concurrent by default? Why or why not?

What does it mean to make a dynamic array thread-safe and concurrent? 使动态数组具有线程安全性和并发性意味着什么? Say, for example, std::vector . 举例来说, std::vector

  1. Two threads may want to insert at the same position. 两个线程可能要插入相同的位置。 No synchronization needed as it will be done as per thread scheduling. 不需要同步,因为它将根据线程调度进行同步。
  2. One thread erasing and another going to access the same element? 一个线程正在擦除而另一个线程将访问同一元素? This is not a data structure issue I believe, it is a usage problem. 我相信这不是数据结构问题,而是使用问题。

So is there anything that needs to be done over std::vector to make it thread-safe and concurrent or is it thread-safe and concurrent by default? 那么,是否有必要在std::vector上进行任何操作以使其成为线程安全并发的,还是默认情况下是线程安全并发的?

C++11 says the following about the thread safetly of containers in the standard library: C ++ 11对标准库中的容器线程安全地说明了以下内容:

23.2.2 Container data races [container.requirements.dataraces] 23.2.2容器数据竞赛[container.requirements.dataraces]

For purposes of avoiding data races (17.6.5.9), implementations shall consider the following functions to be const: begin , end , rbegin , rend , front , back , data , find , lower_bound , upper_bound , equal_range , at and, except in associative or unordered associative containers, operator[] . 为了避免数据争用(17.6.5.9),实现应将以下函数视为const: beginendrbeginrendfrontbackdatafindlower_boundupper_boundequal_rangeat和,除非在关联中或无序关联容器, operator[]

Notwithstanding (17.6.5.9), implementations are required to avoid data races when the contents of the contained object in different elements in the same sequence, excepting vector<bool> , are modified concurrently. 尽管有(17.6.5.9),当同时修改除vector<bool>之外的相同序列中不同元素中所包含对象的内容时,仍需要实现以避免数据争用。

So, basically reading from a container from multiple threads is fine, and modifying elements that are already in the container is fine (as long as they are different elements). 因此,基本上可以从多个线程中读取容器,修改容器中已经存在的元素也可以(只要它们是不同的元素即可)。

So, neither of your two more specific questions are thread safe for std::vector : 因此,您的两个更具体的问题都不是std::vector线程安全的:

1) Two threads inserting into the vector is modifying the vector itself - not existing separate elements. 1)插入到向量中的两个线程正在修改向量本身-不是现有的单独元素。

2) One thread erasing and other walking to access the same element is not safe because erasing an element from the vector isn't an operation that is promised to be thread safe (or "free from data races", as the standard puts it). 2)一个线程擦除和另一个遍历访问同一元素是不安全的,因为从向量中擦除一个元素不是保证线程安全的操作(或如标准所说的那样“没有数据竞争”) 。

To perform those operations safely will require that the program impose some external synchronization itself. 为了安全地执行这些操作,将要求程序本身进行一些外部同步。

The only concurrent operations on a single object in the standard library that are safe by default are - Only accessing const -member functions - All accesses to synchronization primitives (like mutex lock and unlock or atomic operations) Everything else has to be externally synchronized. 在缺省情况下是安全的标准库的单个对象上的唯一的并发操作-仅访问const -member功能-所有访问的同步原语(如互斥锁和解锁或原子操作)拍卖必须被外部同步。 In particular, the standard library doesn't have any thread safe containers yet (as of c++14) 特别是,标准库还没有任何线程安全的容器(自c ++ 14起)

So the answer to both of your examples is no, they both require a form of external synchronization. 因此,这两个示例的答案都是“否”,它们都需要某种形式的外部同步。

What you can do of course is modifying the value of two different elements in the container. 您可以做的当然是修改容器中两个不同元素的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM