怎么能说出条件_variable.wait_ for to not to not of to not of to not of to novious wakeup或cv_status ::超时?
据我所知,只有code> prention_variable.wait_for
带有谓词(因为内部进行双检查)可以避免被虚假的唤醒所掩盖,但没有谓词的版本(如果不是在一定时间内使用)。
但是,如果我只想在cv_status ::超时
发生并通过notify_xxx
做其他事情时,该怎么办? 因为code> prentigh _variable.wait_for
带有谓词返回bool
,它无法确定它是否被notify> notify_xxx
或cv_status :: timeout code>代码>;虽然
code> code_variable.wait_for
没有谓词返回cv_status :: timeout
,但无法分辨它是否被虚假的唤醒或notify_xxxx
。
As far as I know, only condition_variable.wait_for
with predicate(because double check inside) could avoid to be unblocked by spurious wakeup, but not the version without predicate(use if not while).
But what if I want to do something when only cv_status::timeout
happened and do something else by notify_XXX
?
because condition_variable.wait_for
with predicate returns only bool
, it cannot tell if it is unblocked by notify_XXX
or cv_status::timeout
; and although condition_variable.wait_for
without predicate returns cv_status::timeout
, but it cannot tell if it is unblocked by spurious wakeup or notify_XXX
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
条件变量最好用作三重。简历,静音和有效载荷。
没有有效载荷(隐式或明确),就无法确定唤醒是否虚假。
谓词版本可以轻松检查有效载荷,但是在某些复杂的情况下,检查有效载荷的情况可能会更容易而不在lambda中进行。因此提供了另一个API。
修改有效载荷后,条件变量运行的静音必须在发送信号之前处于锁定状态。 (例如,您可以使用MUTEX来保护有效载荷;或者您可以在原子上修改有效载荷,然后锁定并解锁Mutex,然后发送信号)。否则,可能会发生虚假唤醒(错过的信号)的相反。
所有这些都是棘手的,易于意外地误会。
如果您想编写新的并发代码(尤其是使用低级别的原始码),则必须学习足够的C ++内存模型,并学习如何证明您的算法是正确的。因为这是一种方式,因此很难编写代码并基于“有效”来基于其正确性。
您已经正确识别了没有其他数据就无法解决此问题。您需要添加其他数据,并使用它来确定唤醒是虚假的还是真实的。那就是设计。
C ++可以将其他数据添加到条件变量中,但是即使您不使用它,它也会使您付费。条件变量是一个低级别的原始性,使您可以尽可能地编写代码,事实是,它包裹在类中可能会使某些人感到困惑。
而且有很多有效载荷。如果您有一个计数信号量,其中发送信号的数量与接收信号的数量匹配,则有效负载将是一个整数。如果您有一个闩锁或门,一旦打开每个人都可以自由地通过它,那么您的有效载荷将是一个布尔。
现在,您会注意到我正在使用Lambda版本。
我们可以重构非lambda版本:
它更复杂,并且完全相同 相同。 (假设我没有错别字)。
唯一的区别是,您可以做可能不适合Lambda的事情。例如,您可以选择说:“好吧,这是虚假的,但是当我醒着时,我会去其他地方簿记,然后再回来”。
Condition variables are best used as a triple. The cv, the mutex, and the payload.
Without the payload (implicit or explicit), there is no way to determine if the wakeup is spurious or not.
The predicate version makes it easy to check the payload, but in some complex situations checking the payload might be easier without doing it in a lambda. So the other API is provided.
After modifying the payload, the mutex that the condition variable operates on must be in a locked state afterwards before you send signal. (You could guard the payload with the mutex, for example; or you could modify the payload, atomically, then lock and unlock the mutex, then send the signal). Otherwise, the opposite of spurious wakeup (a missed signal) can occur.
All of this is tricky to get right, and easy to accidentally get wrong.
If you want to write new concurrency code (especially using low level primitives), you have to learn enough of the C++ memory model and learn how to prove your algorithms are correct. Because it is way, way to hard to write code and base its correctness based on "does it work".
You have correctly identified that you can't solve this without additional data. You need to add that additional data, and use it to determine if the wakeup was spurious or real. That is by design.
C++ could have added that additional data to condition variable, but then it would have made you pay for it even if you aren't using it. Condition variable is a low level primitive that lets you write code as near to optimal as possible, the fact is it wrapped in a class can be confusing to some people.
And there are lots of payloads. If you have a counting semaphore, where the number of sent signals matches the number of received signals, your payload is going to be an integer. If you have a latch or gate, where once open everyone is free to go through it, your payload is going to be a bool.
now you'll note I'm using the lambda version.
We can refactor to the non-lambda version:
which is more complex, and acts exactly the same. (assuming I have no typos).
The only difference is you could do fancy things that might not fit in a lambda. For example, you could choose to say "well, it was spurious, but while I'm awake I'll go do some bookkeeping somewhere else and come back later".