将虚拟锁传递给 std::condition_variable_any::等待
Passing a dummy lock to std::condition_variable_any::wait
假设有三个线程 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`
}
请注意,mut
在这里根本不用于同步目的,而只是为了适应std::condition_variable::wait
的签名。有了这个观察结果,我想也许我们可以通过实现一个虚拟锁类来做得更好,比如说dummy_lock
,并用std::condition_variable_any
替换std::condition_variable
。 dummy_lock
满足BasicLockable的要求,其所有方法基本上都不做任何事情。因此,我们得到类似于以下内容的代码:
{
dummy_lock lock;
cond_var.wait(lock); // cond_var is a global variable of type std::condition_variable_any`
}
如果有效的话,这应该比原来的效率更高。但问题是,它甚至按照标准工作吗(语言律师在这里很合适(?即使它有效,这绝不是一个优雅的解决方案。那么,你们中有人有更好的想法吗?
你正在一个错误的前提下工作。
互斥锁不仅保护条件谓词,还保护condition_variable本身。
因此,互斥锁应与condition_variable位于同一范围内,并且所有锁都应锁定相同的互斥锁。
喜欢这个:
// global scope
std::mutex mut;
std::condition_variable cond_var;
// thread scope
{
std::unique_lock<std::mutex> lock(mut);
cond_var.wait(lock);
}
看这里: 为什么 pthreads 的条件变量函数需要互斥锁?
你的建议是未定义的行为。关于condition_variable_any
的部分以强调我的
Lock
型必须符合BasicLockable
要求(30.2.5.2(。[ 注意:所有标准互斥锁类型 满足此要求。如果 Lock 类型不是标准互斥锁类型或unique_lock包装器之一 对于标准互斥锁类型与condition_variable_any一起使用,用户必须确保任何必要的 与condition_variable_any
关联的谓词已同步 实例。—尾注 ]
BasicLockable
要求本身不仅描述了接口,还描述了所需的语义:
BasicLockable
L
如果以下表达式格式正确且具有 指定的语义(m 表示 L 类型的值(。
m.lock()
2 效果:阻止,直到可以为当前执行代理获取锁。如果引发异常 则不应为当前执行代理获取锁。
如果你的dummy_lock
实际上没有获得锁,它就不是BasicLockable
,所以你无法满足condition_variable_any
的前提。在这一点上,所有的赌注都落空了,你不能指望wait()
做任何合理的事情。
- 哪些类型可以转换为std::any
- 引用 std::any 或 not_yet_in_std::whatever 的惯用方式是什么?
- std::is_reference from std::any
- 是否可以从 std::any 创建 std::any 与 std::reference_wrapper?
- "reserved for any use"的含义是什么?
- boost::any 如何检查空值/未定义的值
- 我需要std::condition,但有两个以上的选择
- 使用 std::map 存储在 std::any 中,然后通过 std::any_cast 访问
- 可以有效地转换 std::any 与 std::any_cast
- 避免使用 std::any 编写相同的重复类型检查代码
- 广义 std::function (std::any 表示可调用对象)
- 如何在 c++17 中获取存储在 "any" 中的数据大小?
- 从 Any 包中提取和匹配 protobuf 消息类型名的首选方法
- 如何获取"any"当前持有的类型的名称?
- 在可变参数模板函数中存储参数而不使用 boost::any
- 如何将参数包扩展为向量<any>
- 如何使用openssl续订过期的证书密钥或创建自签名证书密钥any.pem Poco c ++
- 在VS2015中访问std::any
- std::any 跨共享库边界在 mingw 中
- 将动态分配对象传递到 boost::any 构造函数中