同一个条件变量的定时等待和无限等待?

Timed waiting and infinite waiting on the same condition variable?

场景:
我有一个基于 condition_variable 的等待和信号机制。这行得通!但我需要的不仅仅是 classic 等待和信号机制。我需要能够进行定时等待和无限等待 "on the same condition_variable"。因此,我围绕 condition_variable 创建了一个包装器 class,它也处理虚假唤醒问题。以下是相关代码:

代码:

// CondVarWrapper.hpp
#pragma once
#include <mutex>
#include <chrono>
#include <condition_variable>

class CondVarWrapper {
public:
    void Signal() {
        std::unique_lock<std::mutex> unique_lock(cv_mutex);
        cond_var_signalled = true;
        timed_out = false;
        unique_lock.unlock();
        cond_var.notify_one();
    }

    bool WaitFor(const std::chrono::seconds timeout) {
        std::unique_lock<std::mutex> unique_lock(cv_mutex);
        timed_out = true;
        cond_var.wait_for(unique_lock, timeout, [this] {
            return cond_var_signalled;
        });
        cond_var_signalled = false;
        return (timed_out == false);
    }

    bool Wait() {
        std::unique_lock<std::mutex> unique_lock(cv_mutex);
        timed_out = true;
        cond_var.wait(unique_lock, [this] {
            return cond_var_signalled;
        });
        cond_var_signalled = false;
        return (timed_out == false);
    }

private:
    bool cond_var_signalled = false;
    bool timed_out  = false;
    std::mutex  cv_mutex;
    std::condition_variable cond_var;
};


// main.cpp
#include "CondVarWrapper.hpp"
#include <iostream>
#include <string>
#include <thread>

int main() {
   CondVarWrapper cond_var_wrapper;

   std::thread my_thread = std::thread([&cond_var_wrapper]{
       std::cout << "Thread started" << std::endl;
        if (cond_var_wrapper.WaitFor(std::chrono::seconds(10))) {
            std::cout << "Thread stopped by signal from main" << std::endl;
        } else {
            std::cout << "ERROR: Thread stopping because of timeout" << std::endl;
        }
    });

   std::this_thread::sleep_for(std::chrono::seconds(3));
   // Uncomment following line to see the timeout working
   cond_var_wrapper.Signal();
   my_thread.join();
}

问题:
上面的代码很好,但我认为有一个问题?我真的可以在 condition_variable 上同时做 waitwait_for 吗?如果一个线程通过调用 CondVarWrapper::Wait() 获得了 cv_mutex 并且这个线程由于某种原因从未 returned 怎么办。然后另一个线程进入调用 CondVarWrapper::WaitFor(std::chrono::seconds(3)),如果它在 3 秒内没有成功,则期望 return 退出。现在,第二个线程将无法在 3 秒后从 WaitFor 中 return,不是吗?事实上,它永远不会 return。因为 condition_variable 等待是定时等待而不是 cv_mutex 上的锁。我对这里的理解是正确的还是错误的?

如果我在上面是正确的,那么我需要用 std::timed_mutex cv_mutex 替换 std::mutex cv_mutex 并在 CondVarWrapper::WaitFor 中执行 timed_wait 并在 [=25 上无限等待=]?或者有什么 better/easier 的处理方法吗?

在条件变量 cond_var 上调用 std::condition::wait 时释放互斥锁。因此,当您从一个线程调用 CondVarWrapper::Wait 时,它会在调用 std::condition::wait 时释放互斥量并永远挂在那里,第二个线程仍然可以调用 CondVarWrapper::WaitFor 并成功锁定互斥量 cv_mutex.