死锁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 可能会在别处改变(即被另一个线程),所以它不会像上面显示的那样优化循环。