如果我的問題重復,我提前道歉,但我無法為我的問題找到令人滿意的答案。
我正在處理以下(可能是愚蠢的)問題:我正在嘗試同步兩個執行緒(A 和 B),并且我想阻止執行緒 A 直到true執行緒 B 設定條件。“特殊”的事情是在執行緒安全物件上檢查條件(例如,讓我們認為它是 a std::atomic_bool)。
我天真的方法如下:
// Shared atomic object
std::atomic_bool condition{false};
// Thread A
// ... does something
while(!condition.load()) ; // Do nothing
// Condition is met, proceed with the job
// Thread B
// ... does something
condition.store(true); // Unlock Thread A
但是,據我了解,這while意味著不希望出現的主動等待。
所以,我想有一個小sleep_for的作為主體while來減少主動等待的頻率,但是問題變成了找到正確的等待時間,這不會導致浪費時間,以防在執行緒 A 處于睡眠狀態時條件解鎖并且,同時,不會使回圈執行過于頻繁。我的感覺是,這在很大程度上取決于執行緒 B 在將條件設定為 true 之前花費的時間,這可能是不可預測的。
我在其他 SO 主題上發現的另一個解決方案是使用條件變數,但這需要引入一個并不真正需要的互斥鎖。
我可能想多了這個問題,但我想知道是否有替代的“標準”解決方案可以遵循(請記住,我僅限于 C 11),一般來說最好的方法是什么。
非常感謝您的幫助。
uj5u.com熱心網友回復:
您的用例很簡單,有很多方法可以實作。第一個建議是使用條件變數。但從你的問題看來,你想避免因為互斥鎖。對于您的用例,我沒有任何分析資料,但對您的用例而言,互斥鎖并不昂貴。
在多執行緒環境中,在某個時間點,您需要一些技術來保護資料的共享訪問和修改。為此,您可能需要互斥鎖。
您可以采用條件變數方法。它符合標準,如果您的用例將來擴展,它還提供通知所有執行緒的功能。此外,正如您提到的“時間”,condition_variable還帶有各種wait*功能,條件可能是“時間”。它可以wait_for或wait_until一定時間。
關于while回圈和sleep_for方法,如果我們以毫秒為單位計算,阻止執行緒執行然后再次重新調度它并不是那么便宜。在這種情況下,條件變數方法會更適合,而不是while回圈和顯式呼叫sleep_for.
uj5u.com熱心網友回復:
抱歉,條件變數是這里的方法。
互斥鎖被用作條件變數的一部分,而不是傳統的互斥鎖。除非出現一些奇怪的優先級反轉情況,否則它應該不會有太多成本。
這是一個簡單的“農場門”。它開始關閉,并且可以打開。一旦打開,就再也無法關閉。
struct gate {
void open_gate() {
auto l = lock();
gate_is_open = true;
cv.notify_all();
}
void wait_on_gate() const {
auto l = lock();
cv.wait(l, [&]{ return gate_is_open; });
}
private:
auto lock() const { return std::unique_lock{m}; }
mutable std::mutex m;
bool gate_is_open = false;
std::condition_variable cv;
};
你會這樣使用:
// Shared gate
gate condition;
// Thread A
// ... does something
condition.wait_on_gate(); // Do nothing
// Condition is met, proceed with the job
// Thread B
// ... does something
condition.open_gate(); // Unlock Thread A
我們終于得到它了。
uj5u.com熱心網友回復:
如何使用某種標記值來檢查執行緒 B 的條件是否為真以解鎖執行緒 A 并在滿足條件后同步它們。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/513353.html
