简体   繁体   English

使用c ++ 11的std :: thread,何时修改全局变量是线程安全的?

[英]Using c++11's std::thread, when is modifying global variables thread-safe?

Consider this source: 考虑以下来源:

#include <string>
#include <iostream>
#include <thread>

using namespace std;

int *up;

void testf(){
    for(int i = 0; i < 1000; i++)
        for(int f = 0; f < 11; f++)
            up[i]++;
}

int main() {
    up = new int[1000];

    std::thread tt[7];

    for(int ts=0;ts<7;ts++) {
        tt[ts]=std::thread(testf);
    }

    for(int ts=0;ts<7;ts++) {
        tt[ts].join();
    }

    for(int i = 0; i < 1000; i++)
        cout << up[i];
    cout << endl;
    delete[] up;
    return 0;
}

I'm purposely writing to the same int array without any mutex. 我故意写没有任何互斥量的同一个int数组。 The for loop in testf() will increment all members of int up[1000] by 11, and we have 7 threads. testf()的for循环会将int up[1000]的所有成员增加11,并且我们有7个线程。 So the output should be 77777777... (2000 Sevens) 所以输出应该是77777777 ...(2000 Sevens)

But sometimes when I run the exe, I get a patch of numbers like this: 但是有时候,当我运行exe时,会得到如下数字:

...7777777066676672756866667777777777777377777366667777777...

Why does this happen? 为什么会这样?

(to compile on linux: g++ -std=c++11 -pthread ) (要在linux上编译:g ++ -std = c ++ 11 -pthread)

The reason is that "up[i]++;" 原因是“ up [i] ++;” is not a thread safe operation. 不是线程安全操作。 It does basically this: 它基本上是这样做的:

  1. read value of up[i] 读取up [i]的值
  2. add one to the read value 将一个加到读取值
  3. write value of up[i] 写入值up [i]

With two threads what should happen: 有两个线程会发生什么:

  • Thread1 1) read value of up[i] (3) 线程1 1)读取up [i]的值(3)
  • Thread1 2) add one to the read value (4) 线程1 2)将一个加到读取值(4)
  • Thread1 3) write value of up[i] (4) 线程1 3)写入up [i]的值(4)

  • Thread2 1) read value of up[i] (4) 线程2 1)读取up [i]的值(4)

  • Thread2 2) add one to the read value (5) Thread2 2)将读取的值加1(5)
  • Thread2 3) write value of up[i] (5) Thread2 3)写值up [i](5)

What could happen: 可能会发生什么:

  • Thread1 1) read value of up[i] (3) 线程1 1)读取up [i]的值(3)
  • Thread2 1) read value of up[i] (3) 线程2 1)读取up [i]的值(3)

  • Thread1 2) add one to the read value (4) 线程1 2)将一个加到读取值(4)

  • Thread1 3) write value of up[i] (4) 线程1 3)写入up [i]的值(4)
  • Thread2 2) add one to the read value (4) 线程2 2)将一加到读取值(4)
  • Thread2 3) write value of up[i] (4) Thread2 3)写值up [i](4)

So both threads write 4 to the array! 因此,两个线程都将4写入数组!

To solve this, you either need a mutex or an atomic increment operation on the array: http://baptiste-wicht.com/posts/2012/07/c11-concurrency-tutorial-part-4-atomic-type.html 要解决此问题,您需要对数组进行互斥或原子递增操作: http : //baptiste-wicht.com/posts/2012/07/c11-concurrency-tutorial-part-4-atomic-type.html

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

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