【发布时间】:2016-09-02 02:31:49
【问题描述】:
在 C++ 中使用全局变量作为参数时,我发现一个奇怪的现象。 这是代码。如果使用 -O2,程序将永远不会结束。
#include <thread>
#include <iostream>
using namespace std;
#define nthreads 2
struct Global{
int a[nthreads];
};
void func(int* a){
while(*a == 0){
}
cout << "done" << endl;
}
struct Global global;
int main(){
thread pid[nthreads];
memset(global.a, 0, nthreads*sizeof(int));
for(int i=0; i<nthreads; i++){
pid[i] = std::thread(func, &global.a[i]);
}
sleep(2);
cout << "finished" << endl;
memset(global.a, 1, nthreads*sizeof(int));
for(int i=0; i<nthreads; i++){
pid[i].join();
}
return 0;
}
如果使用 -O0,一切似乎都正常。 并在while循环中打印变量*a,还是可以的。
所以我猜一定是C++优化的问题。 但是编译器怎么可能对全局变量和多线程进行如此激进的优化呢?
感谢所有答案和 cmets,我尝试使用 volatile,它确实有效。我不想使用互斥锁,因为在每个循环中使用互斥锁都会影响性能。
其实我想做这样的事情:
一个工作线程循环遍历一个全局列表,并在每个 while 循环中执行一些操作。(我不想在这里使用互斥锁,因为即使错误发生在一个循环中也没关系)
其他一些线程可能会将项目添加到此列表中。(这里使用互斥锁是可以的。因为每个线程只添加一次)
我应该怎么做?
【问题讨论】:
-
只在两个线程之一中使用互斥锁是没有意义的——它实际上是一种互斥机制。仅在一侧不起作用。
-
在最后一部分,您所描述的称为生产者-消费者模式。您可能想查看专为此类模式设计的 Boost LockFree。
标签: c++ multithreading global-variables compiler-optimization