为简单起见,假设我们只有一个条件变量来匹配由 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/