簡體   English   中英

c++11兩個臨界區可以使用嵌套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塊中。 這可能是您的意圖,但如果是這樣的話,我認為這不是編寫它以提高可讀性的最佳方式。

此外,如果!ab的關鍵部分很重要,您確實需要保持對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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM