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