将伪锁传递给std :: condition_variable_any :: wait

Lin*_*gxi 5 c++ multithreading locking condition-variable language-lawyer

假设有三个线程A,B和C.B和C在某一点暂停,等待A发信号通知它们继续.在标准C++提供的线程同步工具中,std::condition_variable似乎最适合这里(尽管仍然很糟糕).由于std::condition_variable必须与锁一起使用,因此B和C的代码可能包含以下行:

{
  std::mutex mut;
  std::unique_lock<std::mutex> lock(mut);
  cond_var.wait(lock);  // cond_var is a global variable of type std::condition_variable`
}
Run Code Online (Sandbox Code Playgroud)

注意,mut这里使用的不是用于同步目的,而只是为了符合签名std::condition_variable::wait.有了这个观察,我想也许我们可以通过实现虚拟锁类来做得更好,比方说dummy_lock,并替换std::condition_variablestd::condition_variable_any.dummy_lock符合BasicLockable要求,其所有方法基本上什么都不做.因此,我们得到类似于以下代码:

{
  dummy_lock lock;
  cond_var.wait(lock);  // cond_var is a global variable of type std::condition_variable_any`
}
Run Code Online (Sandbox Code Playgroud)

如果可以的话,这应该比原来的效率更高.但问题是,它是否按照标准运作(语言律师在这里适用)?即使它有效,这绝不是一个优雅的解决方案.那么,你们中的任何人都有更好的想法吗?

Ric*_*ges 3

你正在一个错误的前提下工作。

\n\n

互斥锁不仅保护条件谓词,还保护条件变量本身。

\n\n

因此,互斥锁应该与条件变量处于相同的范围,并且所有锁都应该锁定同一个互斥锁。

\n\n

像这样:

\n\n
// global scope\nstd::mutex mut;\nstd::condition_variable cond_var;\n\n// thread scope\n{\n  std::unique_lock<std::mutex> lock(mut);\n  cond_var.wait(lock);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

请参阅此处:为什么 pthreads\xe2\x80\x99 条件变量函数需要互斥体?

\n