简体   繁体   English

std :: condition_variable没有锁

[英]std::condition_variable without a lock

I'm trying to synchonise a set of threads. 我正在尝试同步一组线程。 These threads sleep most of the time, waking up to do their scheduled job. 这些线程大多数时候都处于睡眠状态,醒来便完成了预定的工作。 I'm using std::thread for them. 我正在为他们使用std::thread

Unfortunately, when I terminate the application threads prevent it from exiting. 不幸的是,当我终止应用程序线程时,它无法退出。 In C# I can make a thread to be background so that it will be termianted on app exit. 在C#中,我可以使线程成为background以便在应用程序退出时终止该线程。 It seems to me that equavalint feature is not availabe at C++. 在我看来,E ++ valint功能在C ++中不可用。

So I decided to use a kind of event indicator, and make the threads to wake up when the app exits. 因此,我决定使用一种事件指示器,并使线程在应用程序退出时唤醒。 Standard C++11 std::condition_variable requires a unique lock, so I cannot use it, as I need both threads to wake up at the same time (they do not share any resources). 标准C ++ 11 std::condition_variable需要唯一锁,因此我无法使用它,因为我需要两个线程同时唤醒(它们不共享任何资源)。

Eventually, I decided to use WinApi's CreateEvent + SetEvent + WaitForSingleObject in order to solve the issue. 最终,我决定使用WinApi的CreateEvent + SetEvent + WaitForSingleObject来解决此问题。

I there a way to achieve the same behavior using just c++11? 我有一种方法可以仅使用c ++ 11来实现相同的行为?

Again, what do I want: 同样,我想要什么:

  1. a set of threads are working independently and usually are asleep for a particular period (could be different for different threads; 一组线程是独立工作的,通常在特定时间段内处于睡眠状态(不同的线程可能会有所不同;
  2. all threds check a variable that is availabe for all of them whether it is a time to stop working (I call this variable IsAliva ). 所有对象都检查是否有时间停止工作(我称此变量为IsAliva )。 Actually all threads are spinning in loop like this: 实际上,所有线程都像这样在循环中旋转:

     while (IsAlive) { // Do work std::this_thread::sleep_for(...); } 
  3. threads must be able to work simultaneously, not blocking each other; 线程必须能够同时工作,而不是相互阻塞;
  4. when the app is closed and event is risen and it makes the thread to wake up right now, no matter the timeout; 当应用关闭且事件触发时,无论超时如何,线程都立即唤醒。
  5. waken up, it checks the IsAlive and exits. 唤醒后,它会检查IsAlive并退出。

yes you can do this using standard c++ mechanisms of condition variables, a mutex and a flag of somekind 是的,您可以使用条件变量,互斥锁和某种标记的标准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;
   }
}

Note that this runs correctly in the face of death being triggered before entering the condition. 请注意,这在进入条件之前面对死亡触发时可以正确运行。 You could also use the return value from wait_for but this way is easier to read imo. 您也可以使用wait_for的返回值,但是这种方式更易于阅读imo。 Also, whilst its not clear, multiple threads sleeping is fine as the wait_for code internally unlocks the unique_lock whilst sleeping and reacquires it to check the condition and also when it returns. 另外,虽然不清楚,但多个线程休眠是可以的,因为wait_for代码在休眠时内部解锁了unique_lock并重新获取它以检查条件以及返回状态。

Finally, all the threads do wake up 'at the same time' as whilst they're serialised in checking the bool flag, this is only for a few instructions then they unlock the lock as they break out of the loop. 最后,所有线程的确在检查bool标志被序列化时“同时”唤醒,这仅适用于几条指令,然后在它们退出循环时便解锁了锁。 It would be unnoticeable. 这将是不明显的。

在c ++ 11中,您应该能够detach()线程,以便将其视为守护程序线程,这意味着如果应用程序终止,该线程将自动停止。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM