考虑这个来源:
#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;
}
我故意在没有任何互斥锁的情况下写入相同的int数组。 testf()
中的for循环将int up[1000]
的所有成员增加11,我们有7个线程。所以输出应该是77777777 ......(2000 Sevens)
但有时当我运行exe时,我会得到一些像这样的数字:
...7777777066676672756866667777777777777377777366667777777...
为什么会这样?
(在linux上编译:g ++ -std = c ++ 11 -pthread)
答案 0 :(得分:6)
原因是&#34; up [i] ++;&#34;不是线程安全的操作。它基本上是这样的:
有两个线程会发生什么:
Thread1 3)写入up [i](4)
Thread2 1)读取up [i](4)
会发生什么:
Thread2 1)读取up [i](3)
Thread1 2)在读取值(4)
因此两个线程都向数组写入4!
要解决此问题,您需要对数组执行互斥或原子递增操作: http://baptiste-wicht.com/posts/2012/07/c11-concurrency-tutorial-part-4-atomic-type.html