I find a strange phenomenon when using global variable as parameter in C++. Here is the code. The program would never end if using -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;
}
If using -O0, everything seems ok. And print variable *a in while loop, it is still ok.
So I guess it must be the problem of C++ optimization. But How could compiler make such an aggressive optimization for global variable and multi-thread?
Thanks for all answers and comments, I tried to use volatile and it does work. I don't want to use mutex because using mutex in every loop influence the performance.
In fact, I want to do something like this:
A worker thread loops through a global list and does some execution in each while loop.(I don't want use mutex here, because it does not matter even though mistake happens in just one loop)
Some other threads would possibly add items to this list.(mutex used here is ok. because each thread just adds one time)
What should I do correctly?