死锁C++线程条件变量
deadlock c++ thread condition variable
我有一个名为 Workers 的 class 问题。
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;});
}
主要 :
Workers workers* = new Workers(1);//Only one thread worker
workers->startWork(0);
workers->stopWork(0);
问题是在
中从未发现变量 endWork 为真
for(;!endWork;);
但是,这个在 stopWork 方法中设置为真:
endWork=true;
如果我替换
for(;!endWork;);
来自
for(;!endWork;){printf("work\n");}
程序运行良好!
我的错误是什么?
期待您的回复。
for(;!endWork;){printf("work\n");}
The program works well ! What is my error ?
由于变量 endWork
是一个常规变量,具有高优化选项的编译器(即 -O3
)可能会假设变量不会改变并优化循环内的读取,即它转换循环:
for( ; !endWork; ) ;
到
if(!endWork) for (;;) ;
在 printf()
中发生了太多事情,所以如果我们在 printf()
中更改 endWork
变量,编译器无法判断。所以,它并没有像上面那样优化循环。
如何处理这个问题?最简单的方法是将 endWork
声明为易变的。这会给编译一个提示,值 endWork
可能会在别处改变(即被另一个线程),所以它不会像上面显示的那样优化循环。
我有一个名为 Workers 的 class 问题。
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;});
}
主要 :
Workers workers* = new Workers(1);//Only one thread worker
workers->startWork(0);
workers->stopWork(0);
问题是在
中从未发现变量 endWork 为真for(;!endWork;);
但是,这个在 stopWork 方法中设置为真:
endWork=true;
如果我替换
for(;!endWork;);
来自
for(;!endWork;){printf("work\n");}
程序运行良好! 我的错误是什么?
期待您的回复。
for(;!endWork;){printf("work\n");}
The program works well ! What is my error ?
由于变量 endWork
是一个常规变量,具有高优化选项的编译器(即 -O3
)可能会假设变量不会改变并优化循环内的读取,即它转换循环:
for( ; !endWork; ) ;
到
if(!endWork) for (;;) ;
在 printf()
中发生了太多事情,所以如果我们在 printf()
中更改 endWork
变量,编译器无法判断。所以,它并没有像上面那样优化循环。
如何处理这个问题?最简单的方法是将 endWork
声明为易变的。这会给编译一个提示,值 endWork
可能会在别处改变(即被另一个线程),所以它不会像上面显示的那样优化循环。