【问题标题】:std::condition_variable without a lock没有锁的 std::condition_variable
【发布时间】:2016-08-17 23:15:15
【问题描述】:

我正在尝试同步一组线程。这些线程大部分时间都在休眠,醒来完成他们预定的工作。我正在为他们使用std::thread

不幸的是,当我终止应用程序线程时,会阻止它退出。在 C# 中,我可以将线程设为background,以便在应用退出时终止。在我看来,等价林特性在 C++ 中不可用。

所以我决定使用一种事件指示器,让线程在应用退出时唤醒。标准 C++11 std::condition_variable 需要一个唯一的锁,所以我不能使用它,因为我需要两个线程同时唤醒(它们不共享任何资源)。

最终,我决定使用 WinApi 的CreateEvent + SetEvent+WaitForSingleObject 来解决问题。

我有办法只使用 c++11 来实现相同的行为吗?

再次,我想要什么:

  1. 一组线程独立工作,通常处于休眠状态 特定时期(不同线程可能不同;
  2. 所有 threds 都会检查一个变量是否可供所有人使用 现在是停止工作的时候了(我称这个变量为IsAliva)。 实际上所有线程都像这样循环旋转:

    while (IsAlive) {
      // Do work
      std::this_thread::sleep_for(...);
    }
    
  3. 线程必须能够同时工作,不能互相阻塞;
  4. 当应用程序关闭并引发事件时,它使线程 立即醒来,无论超时;
  5. 醒来,​​它会检查 IsAlive 并退出。

【问题讨论】:

  • 我不明白第 4 点和第 5 点。
  • 该事件使线程在超时结束前唤醒。
  • “他们不共享任何资源”“所有线程检查一个变量[..]IsAlive不兼容。跨度>
  • 此变量受互斥体保护。
  • 你使用唯一的锁来保护这个变量只有条件变量。

标签: c++ multithreading c++11 mutex


【解决方案1】:

是的,您可以使用条件变量、互斥体和某种标志的标准 C++ 机制来做到这一点

// Your class or global variables
std::mutex deathLock;
std::condition_variable deathCv;
bool deathTriggered = false;

// Kill Thread runs this code to kill all other threads:
{
    std::lock_guard<std::mutex> lock(deathLock);
    deathTriggered = true;
}
deathCv.notify_all();

// You Worker Threads run this code:
while(true)
{
   ... do work

   // Now wait for 1000 milliseconds or until death is triggered:
   std::unique_lock<std::mutex> lock(deathLock);
   deathCv.wait_for(lock, std::chrono::milliseconds(1000), [](){return deathTriggered;});

   // Check for death
   if(deathTriggered)
   {
      break;
   }
}

请注意,在进入条件之前触发死亡时,这会正确运行。您也可以使用 wait_for 的返回值,但这种方式更易于阅读 imo。此外,虽然不清楚,但多个线程休眠是可以的,因为 wait_for 代码在内部解锁 unique_lock 并在休眠时重新获取它以检查条件以及何时返回。

最后,所有线程确实“同时”唤醒,因为它们在检查 bool 标志时被序列化,这仅适用于几条指令,然后它们在脱离循环时解锁锁。不会引起注意的。

【讨论】:

    【解决方案2】:

    在c++11中,你应该可以detach()一个线程,这样它就会被视为一个守护线程,这意味着如果应用程序终止,线程将自动停止。

    【讨论】:

    猜你喜欢
    • 2018-03-01
    • 2022-10-08
    • 2018-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-22
    • 2023-03-13
    相关资源
    最近更新 更多