我需要同步std::condition_variable/condition_variable_any::notify_one
?我需要同步的std :: condition_variable/condition_variable_any :: notify_one
至於我可以看到,如果丟失的通知是可以接受的 - 這是確定調用notify_one
不受保護(mutex所爲例)。
舉例來說,我看到了下面的使用模式(抱歉,不記得在哪裏):
{
{
lock_guard<mutex> l(m);
// do work
}
c.notify_one();
}
但是,我考察的libstdC++源代碼,我看到:
condition_variable::notify_one
void condition_variable::notify_one() noexcept
{
int __e = __gthread_cond_signal(&_M_cond);
// XXX not in spec
// EINVAL
if (__e)
__throw_system_error(__e);
}
and condition_variable_any::notify_one:
void condition_variable_any::notify_one() noexcept
{
lock_guard<mutex> __lock(_M_mutex);
_M_cond.notify_one();
}
這裏是condition_variable_any的佈局:
class condition_variable_any
{
condition_variable _M_cond;
mutex _M_mutex;
// data end
即它只是在condition_variable + mutex周圍的薄包裝。
所以,問題:
- 它是線程安全的,不會被用於互斥或者
condition_variable_any
或condition_variable
保護notify_one
? - 爲什麼condition_variable_any的實現使用額外的互斥量?
- 爲什麼實施
condition_variable_any::notify_one
和condition_variable::notify_one
有所不同?可能condition_variable::notify_one
需要手動保護,但condition_variable_any::notify_one
不需要?它是libstdC++的錯誤?
謝謝!這幫助了我很多。特別回答2和3 - 關於原子性的好處,以及無論如何都使用互斥體的內部元素。順便說一句,您可以添加指向pthread_cond_wait http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_cond_wait.html的鏈接,以顯示最常見的實現僅適用於內部中它自己的互斥體。你能否澄清一下你的意思是「這裏有一些非常微妙的代碼」。 – qble 2013-04-09 20:31:33
關於1. - 可否鎖定condition_variable :: notify_one導致錯過通知?即線程#1在互斥體中執行任務,發送結果,解鎖互斥體,[同時]線程#2鎖定互斥體但尚未調用wait,[同時]線程#1調用notify_one,[同時]線程#2調用wait - 通知丟失。 – qble 2013-04-09 20:37:04
這不是一個丟失的通知,這是等待線程在等待之前不檢查條件謂詞。鎖定互斥鎖並不能解決這種情況,通知仍可能在等待線程鎖定互斥鎖之前發生。您**必須在等待條件變量時檢查關聯的謂詞 – 2013-04-10 00:27:24