c++ - 使用 std::conditional_variable 等待条件

标签 c++ multithreading c++11 blocking condition-variable

为简单起见,假设我们只有一个条件变量来匹配由 bool 值反射(reflect)的单个条件。

1) 为什么 std::condition_variable::wait(...) 在发送“通知”以解除 sleep 后再次锁定互斥体?

2) 看到“1)”中的行为,这是否意味着当您执行 std::condition_variable::notify_all 时,它只会让所有等待的线程都被解锁/唤醒向上...但是按顺序而不是一次全部?如果是这样,可以做些什么来一次完成所有工作?

3) 如果我只关心线程在满足条件之前处于休眠状态,而不关心任何互斥锁的获取,我该怎么办?是否有替代方案或当前的 std::condition_variable::wait(...) 方法应该围绕此进行黑客攻击?

如果要使用“hackery”,这个函数是否可以在某个条件下解除阻塞所有等待线程,它是否可以从任何(每个线程)线程调用:

//declared somehwere and modified before sending "notify"(ies)
std::atomic<bool> global_shared_condition_atomic_bool;

//the single(for simplicity in our case) condition variable matched with the above boolean result
std::condition_variable global_shared_condition_variable;

static void MyClass:wait()
{
    std::mutex mutex;
    std::unique_lock<std::mutex> lock(mutex);

    while (!global_shared_condition_atomic_bool) global_shared_condition_variable.wait(lock);
}

它会像这样从随机的​​“等待”线程中调用:

void random_thread_run()
{
    while(someLoopControlValue)
    {
        //random code...
        MyClass:wait(); //wait for whatever condition the class+method is for.
        //more random code...
    }
}

编辑:

门类

#ifndef Gate_Header
#define Gate_Header

#include <mutex>
#include <condition_variable>

class Gate
{
public:
    Gate()
    {
        gate_open = false;
    }

    void open()
    {
        m.lock();
        gate_open = true;
        m.unlock();

        cv.notify_all();
    }

    void wait()
    {
        std::unique_lock<std::mutex> lock(m);

        while (!gate_open) cv.wait(lock);
    }

    void close()
    {
        m.lock();
        gate_open = false;
        m.unlock();
    }

private:
    std::mutex m;
    std::condition_variable cv;
    bool gate_open;
};

#endif

最佳答案

条件变量虚假地唤醒事物。

必须有一个互斥量并且它必须保护某种消息以使它们工作,否则您无法保证任何此类唤醒发生。

之所以这样做,大概是因为无论如何,非伪造版本的有效实现最终都是根据这样的伪造版本来实现的。

如果您无法使用互斥锁来保护消息编辑(即,没有对其进行同步,则消息的状态是未定义的行为。这可能会导致编译器优化内存读取以在第一次读取后跳过它。

即使排除未定义的行为(假设您使用原子),也存在设置消息、发生通知的竞争条件,如果您未能在设置变量和通知条件变量之间的时间。

除非极端情况,否则您通常希望使用 wait 的 lambda 版本。

除非您同时审计通知代码和等待代码,否则无法审计条件变量代码。

struct gate {
  bool gate_open = false;
  mutable std::condition_variable cv;
  mutable std::mutex m;

  void open_gate() {
    std::unique_lock<std::mutex> lock(m);
    gate_open=true;
    cv.notify_all();
  }
  void wait_at_gate() const {
    std::unique_lock<std::mutex> lock(m);
    cv.wait( lock, [this]{ return gate_open; } );
  }
};

  void open_gate() {
    {
      std::unique_lock<std::mutex> lock(m);
      gate_open=true;
    }
    cv.notify_all();
  }

关于c++ - 使用 std::conditional_variable 等待条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41769934/

相关文章:

c++ - 无法 emplace_back 具有 const 成员的类的实例

c++ - 如何防止QT事件堆栈溢出?

c++ - C++查询子进程的方法

c++ - 当另一个进程写入新行时从文件中读取

c# - 具有多线程服务的数据库连接池

java - 为什么 java.util.concurrent.ArrayBlockingQueue 在调用 await() 时使用 'while' 循环而不是 'if'?

c++ - 模板类中 operator* 的尾随返回类型

c++ - GCC -Wshadow 缺少一些案例吗?

C++ thread_id 是什么数据类型,它可以分配给变量吗?

c++ - 共享从属对象