【问题标题】:Thread synchronisation: Wait on two bool variables线程同步:等待两个布尔变量
【发布时间】:2016-04-07 11:12:53
【问题描述】:

我想在一个线程中等待两个bool 变量为真。它们在不同的地方被改变。我可以在我的项目中使用 boost,但不能在 C++11 中使用。 我确实找到了有关如何使用互斥锁和条件变量的信息,但我不确定是否可以等待两个互斥锁。 这是我的程序的一些伪代码。

bool job1_dataready, job2_dataready;

//t1:
void job1()
{
   //do stuff
   job1_dataready = true;
}

//t2:
void job2()
{
   //do stuff
   job2_dataready= true;
}

main()
{
 boost::thread t1(job1);
 boost::thread t1(job2);

 if(job1_dataready&& job2_dataready)
 {
    //do stuff with data from both jobs
 }

}

【问题讨论】:

  • 您似乎忘记在问题中包含问题。
  • 您的布尔值不受互斥锁或其他同步机制的保护,也不是原子的。这意味着来自主线程和工作线程的访问将是不同步的,因此是未定义的行为。 (这不是您问题的答案,只是为了指出您当前的尝试不会去任何地方。)

标签: c++ multithreading thread-safety thread-synchronization


【解决方案1】:

据我所知,您不需要 bool 变量,请改用 std::thread::join

main() {
    std::thread t1(job1);
    std::thread t1(job2);
    t1.join();
    t2.join();
    // do jobs after threads t1 and t2 finish working
}

【讨论】:

  • 一个小问题的完美答案 - OP 声明不使用 C++11,但使用 boost。要获得出色的答案,请考虑使用 boost 表达相同的内容。
  • 完美解决我的问题。我正在使用boost::thread of course
【解决方案2】:

您将阻塞条件变量,在唤醒时检查您的布尔值,然后返回等待或继续处理。您的线程将在设置布尔标志后向条件变量发出信号。当然,所有这些都带有适当的互斥锁。您可以等待无限多个条件,只需检查条件阻塞后何时唤醒即可。

【讨论】:

    【解决方案3】:

    在这种简单的情况下,您只需按顺序锁定两个互斥锁即可等待它们。首先从线程 1 锁定互斥锁,然后从线程 2 锁定互斥锁。如果线程 2 将在线程 1 之前完成,则在锁定互斥锁 2 时主线程不会阻塞。

    但是,请注意,这是您问题的答案,而不是您问题的解决方案。原因是您与互斥锁存在竞争条件:主线程可能会在工作线程启动之前锁定互斥锁。因此,虽然 Andrei R.s 的回复 (std::thread::join) 不是直接答案,但它是正确的解决方案。

    【讨论】:

      【解决方案4】:

      如果你打算在各自的线程终止之前设置你的两个bools,那么Andrei R.'s solution 只是join 两个线程绝对是最好的方法。但是,如果您的线程在达到dataready 点后实际上继续工作,因此还没有终止,那么您需要一种不同的方法。在这种情况下,您可以使用两个 std::future/std::promise 对象,它们看起来像这样:

      std::promise<bool> job1_dataready, job2_dataready;
      
      //t1:
      void job1()
      {
        //do stuff
        job1_dataready.set_value(true); // The value doesn't actually matter
        //do more stuff
      }
      
      //t2:
      void job2()
      {
        //do stuff
        job2_dataready.set_value(true);
        //do more stuff
      }
      
      main()
      {
        std::future<bool> job1_future = job1_dataready.get_future();
        std::future<bool> job2_future = job2_dataready.get_future();
      
        boost::thread t1(job1);
        boost::thread t2(job2);
      
        job1_future.wait();
        job2_future.wait();
        if (job1_future.get() && job2_future.get()) // True unless something was aborted
        {
          //do stuff with data from both jobs
        }
      }
      

      【讨论】:

      • 这看起来很有希望。不幸的是,我不能使用 c++11,而且我的 boost 版本中似乎不存在 boost::future(1.49,无法更新)。
      • 嗯,根据 1.49.0 的文档,应该有 boost::unique_future
      猜你喜欢
      • 2015-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-08
      • 2021-09-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多