![](/img/trans.png)
[英]How to implement scoped_lock functionality in c++11 using lock_guard
[英]c++11 two critical sections can use nested lock_guard?
如果我有兩個臨界區,我分別做了兩個對應的互斥鎖來保護它們。(我認為有必要精確控制何時鎖定,因為它們在不同的時間和場景中使用, Q1
:真的是這樣嗎?)例如:
bool a;//ignore atomic_bool, because in actual, the data structure is more complex
mutex mut_a;//for threadsafe of a
bool b;
mutex mut_b;//for threadsafe of b
我需要實現這種邏輯:
if (lock_guard<mutex> lck(mut_a);a) { do something...
}
else {
if (lock_guard<mutex> lck(mut_b);b) { do something...
}
}
如所見,lock_guard(mutex) 是嵌套使用的, Q2
是否正確且線程安全?
我認為這里的一個問題是
if (bool x = true)
{
// x is in scope
}
else
{
// x is STILL in scope!
x = false;
}
所以mut_a
上的第一個鎖仍然保存在else
塊中。 這可能是您的意圖,但如果是這樣的話,我認為這不是編寫它以提高可讀性的最佳方式。
此外,如果!a
在b
的關鍵部分很重要,您確實需要保持對a
的鎖定。
代碼本身並不是不安全的。 然而, ...
正如另一個答案中已經提到的,您需要考慮互斥鎖也在 else 分支中被鎖定:
if (lock_guard<mutex> lck(mut_a);a) { do something...
// mut_a is locked
} else {
if (lock_guard<mutex> lck(mut_b);b) { do something...
// mut_a and mut_b are locked
}
}
也許這是故意的。 如果不是,那么它是錯誤的。
此外,您需要小心同時鎖定多個互斥鎖。 當您在其他地方以不同的順序鎖定它們時,將會出現死鎖:
{
lock_guard<mutex> lock_b(mut_b);
lock_guard<mutex> lock_a(mut_a);
// do something
}
您的代碼鎖定mut_a
並且僅在它能夠獲得mut_b
上的鎖定后才釋放它。 此代碼鎖定mut_b
並且僅在它能夠獲得mut_a
上的鎖定后才釋放它。
為了避免這種死鎖,您可以使用std::scoped_lock
,它采用多個互斥鎖並使用一些死鎖避免算法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.