是否在向量C ++中读取和写入向量线程安全操作? [重复]

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是否在向量C ++中读取和写入向量线程安全操作? [重复]相关的知识,希望对你有一定的参考价值。

这个问题在这里已有答案:

我有一个下面的代码,有时会给出分段错误?

vector<int> myvector;
void function1()

    for(int i = 0;i<10;i++)
    
        cout<<"writer thread:"<<i<<endl;
        myvector.push_back(i);
    

void function2()

    for(int i = 0;i<10;i++)
    
        cout<<"reader thread:";
        cout<<myvector[i]<<endl;
    

int main()


    thread t1(function1);
    thread t2(function2);

    t1.join();
    t2.join();

我对一般的容器上的线程安全规则/保证以及特别是向量很困惑。我在一次采访中被问到这个问题并没有说出为什么它在线程上写入并在其他线程中写入不是线程安全的操作。

在下面的向量push_back链接我看到“否则,没有访问现有元素,并且在Data Race部分下同时访问或修改它们是安全的”。这个语句如何证明向量写操作不是线程安全的?

http://www.cplusplus.com/reference/vector/vector/push_back/

答案

来自Scott Meyers,Effective STL,第12项:“对STL容器的螺纹安全性有现实的期望”。

  • 多个读者是安全的。多个线程可以同时读取单个容器的内容,这将正常工作。当然,在阅读过程中不得有任何作家对集装箱采取行动。
  • 对不同容器的多个编写者是安全的。多个线程可以同时写入不同的容器。

这就是全部,让我明确指出这是你可以期待的,而不是你所期望的。

我想我不必在这里提供任何额外的解释:)

另一答案

这是不安全的。想象一下,你只是先运行第二个线程,而且只有(完成之后)才开始执行第一个线程。你认为你的代码会怎么做?

因此,即使std::vector对于并发访问是超级线程安全的(它不是),代码仍然是非常错误的。

另一答案

不,std::vector<>如何使用它不是线程安全的。在以下情况下,它只是线程安全的:

  1. 所有线程只从向量中读取
  2. 如果一个线程写入向量,则没有并发读取操作。

function2function1更早/更快地运行时发生分段错误。 ``function1I例如访问myvector[4],它没有被推送到矢量。在这种情况下,您将获得访问失败的错误,并且,根据系统的其余部分正在执行的操作,这可能导致读取错误的数据或分段错误。

另一答案

规则是:如果您在线程之间访问了共享对象,并且这些线程中至少有一个是编写器,那么您需要同步。没有它你就有数据竞争,这是未定义的行为。

在你的情况下,因为你在写入时从向量中读取它,它绝对不是线程安全的。

以上是关于是否在向量C ++中读取和写入向量线程安全操作? [重复]的主要内容,如果未能解决你的问题,请参考以下文章

在 C 或 C++ 中的同一个套接字上同时读取和写入

C ++如果一个线程写入一旦完成就会切换一个布尔值,那么在另一个线程的循环中读取该布尔值是不是安全?

使用多线程在 GNU C 中使用写入函数是不是安全

C 读取和线程安全 (linux)

c++ 当在一个线程中写入并在第二个线程中读取同一个对象时会发生啥? (它安全吗?)[重复]

Visual C++ 2010 中的 STL 映射实现和线程安全