Reputation: 13
I have a problem with a class called Workers.
Workers::Workers(int _nbThreads):
goWork(false),
progressWork(false),
endWork(false),
endFinishedWork(false),
nbThreads(_nbThreads)
{
for(int i=0;i<nbThreads;i++){
threads.push_back(new std::thread(&Workers::threadsExecute,this,i));
}
}
void Workers::threadsExecute(int numThread){
for(;;){
std::unique_lock<std::mutex> uniqueMutexWork(mutexWork);
conditionWorkStarted.wait(uniqueMutexWork, [this] {return goWork==true;});
progressWork=true;
mutexWork.unlock();
conditionWorkProgress.notify_all();
for(;!endWork;);
mutexWork.lock();
endFinishedWork=true;
mutexWork.unlock();
conditionWorkFinished.notify_all();
break;
}
}
void Workers::threadsEnd(){
for(int i=0;i<nbThreads;i++){
threads[i]->join();
}
}
void Workers::startWork(int numThread){
std::unique_lock<std::mutex> uniqueMutexWork(mutexWork);
goWork=true;
conditionWorkStarted.notify_all();
conditionWorkProgress.wait(uniqueMutexWork, [this] {return progressWork==true;});
}
void Workers::stopWork(int numThread){
std::unique_lock<std::mutex> uniqueMutexWork(mutexWork);
endWork=true;
conditionWorkFinished.wait(uniqueMutexWork, [this] {return endFinishedWork==true;});
}
The main :
Workers workers* = new Workers(1);//Only one thread worker
workers->startWork(0);
workers->stopWork(0);
The problem is that the variable endWork is never found to true in
for(;!endWork;);
However, this one is well put to true in the stopWork method :
endWork=true;
If I replace
for(;!endWork;);
by
for(;!endWork;){printf("work\n");}
The program works well ! What is my error ?
I look forward to your response.
Upvotes: 1
Views: 67
Reputation: 8534
for(;!endWork;){printf("work\n");}
The program works well ! What is my error ?
Since the variable endWork
is a regular variable, compiler with high optimization option (i.e. -O3
) might assume the variable does not change and optimize out the read inside the loop, i.e. it transforms the loop:
for( ; !endWork; ) ;
to
if(!endWork) for (;;) ;
With printf()
there are too many things going on, so the compiler cannot figure out if we change endWork
variable inside the printf()
. So, it does not optimize the loop as shown above.
How to deal with the issue? The simplest would be to declare endWork
as volatile. This will give compilation a hint, that the value endWork
might be changed elsewhere (i.e. by another thread), so it will not optimize the loop as showed above.
Upvotes: 0