条件变量不起作用,但在添加std :: cout之后,它正在工作

时间:2015-06-15 07:40:34

标签: c++ multithreading boost boost-thread

我的项目由两个线程组成:一个主线程和另一个处理另一个窗口内容的线程。因此,当主线程要求另一个窗口更新自身时,它调用draw函数,如下所示:

while contains(currentCardValues, randomNumber + 1) {

draw函数只是告诉另一个线程接收到一个新任务。

void SubApplicationManager::draw() {

  // Zero number of applications which has finished the draw counter
  {
    boost::lock_guard<boost::mutex> lock(SubApplication::draw_mutex);
    SubApplication::num_draws = 0;
  }

  // Draw the sub applications.
  for (size_t i = 0; i < m_subApplications.size(); i++)
    m_subApplications[i].signal_draw();

  // Wait until all the sub applications finish drawing.
  while (true){
    boost::lock_guard<boost::mutex> lock(SubApplication::draw_mutex);
    std::cout << SubApplication::num_draws << std::endl;
    if (SubApplication::num_draws >= m_subApplications.size()) break;
  }

}

其他线程的主体如下。它等待任务到达然后开始处理:

void SubApplication::signal_draw() {

  task = TASK::TASK_DRAW;
  {
    boost::lock_guard<boost::mutex> lock(task_received_mutex);
    task_received = true;
  }
  task_start_condition.notify_all();

}

问题在于,如果我按原样运行代码,它永远不会运行void SubApplication::thread() { clock_t start_time, last_update; start_time = last_update = clock(); //! Creates the Sub Application init(); while (!done) // Loop That Runs While done=FALSE { // Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene() if (active) // Program Active? { // Wait here, until a update/draw command is received. boost::unique_lock<boost::mutex> start_lock(task_start_mutex); while (!task_received){ task_start_condition.wait(start_lock); } // Task received is set to false, for next loop. { boost::lock_guard<boost::mutex> lock(task_received_mutex); task_received = false; } clock_t frame_start_time = clock(); switch (task){ case TASK_UPDATE: update(); break; case TASK_DRAW: draw(); swapBuffers(); break; case TASK_CREATE: create(); break; default: break; } clock_t frame_end_time = clock(); double task_time = static_cast<float>(frame_end_time - frame_start_time) / CLOCKS_PER_SEC; } } } 的其他线程,但如果我在task = TASK::TASK_DRAW;的开头添加std::cout << "Draw\n";,它将会尽职尽责。我正在寻找它正在发生的原因以及解决它的常用方法是什么?

2 个答案:

答案 0 :(得分:1)

作为首发,请在task_start_condition锁定下发出task_start_mutex信号。

考虑在创建线程期间锁定该互斥锁,以避免明显的比赛。

第三:似乎你有几个以“逻辑任务”(draw,start)命名的互斥体。然而,实际上,互斥锁保护资源,而不是“逻辑任务”。因此,在他们应该保护的共享资源之后命名它们是一种好习惯。 _(在这种情况下,我得到的印象是单个互斥锁可能足够/更好。但我们无法从显示的代码中确定))。

答案 1 :(得分:1)

boost::lock_guard<boost::mutex> lock(task_received_mutex);
task_received = true;

好的,task_received_mutex保护task_received

    boost::unique_lock<boost::mutex> start_lock(task_start_mutex);
    while (!task_received){
      task_start_condition.wait(start_lock);
    }

哎呀,我们正在阅读task_received而没有拿着保护它的互斥锁。是什么阻止了一个线程在另一个线程正在修改它时读取task_received的竞争?这可能会立即导致僵局。

此外,您有代码声称“等到所有子应用程序完成绘图”,但没有调用任何等待函数。所以它实际上是旋转而不是等待,这很糟糕。