[英]Is it necessary to lock?
我在leetcode中遇到了一個問題。 我已經在討論中查看了一些解決方案。 但是我的解決方案與其他解決方案不同,因為我沒有first
在方法中使用lock
。 我想知道我的代碼是否正確。 此外,您能給我一些有關我的代碼的建議嗎?
我認為沒有必要像void second(function<void()> printSecond)
unique_lock
在方法void first(function<void()> printFirst)
void second(function<void()> printSecond)
,對嗎?
class Foo {
public:
Foo() {
}
void first(function<void()> printFirst) {
// cout<<1<<endl;
// printFirst() outputs "first". Do not change or remove this line.
// mtx.lock();
printFirst();
flag=1;
// mtx.unlock();
cond.notify_all();
// cout<<11<<endl;
}
void second(function<void()> printSecond) {
// cout<<2<<endl;
{
unique_lock<mutex> lk(mtx);
cond.wait(lk,[this](){return flag==1;});
// printSecond() outputs "second". Do not change or remove this line.
printSecond();
flag=2;
}
// cout<<22<<endl;
cond.notify_all();
}
void third(function<void()> printThird) {
// cout<<3<<endl;
unique_lock<mutex> lk(mtx);
cond.wait(lk,[this](){return flag==2;});
// printThird() outputs "third". Do not change or remove this line.
printThird();
flag=3;
// cout<<33<<endl;
}
mutex mtx;
condition_variable cond;
int flag=0;
};
顯然,您的三個元素函數應該由不同的線程調用。 因此,您需要在每個線程中鎖定互斥對象,以保護公共變量flag
不被並發訪問。 所以,你應該取消注釋mtx.lock()
和mtx.unlock()
在first
以保護它有作為。 second
和third
函數應用unique_lock
作為替代方法。
始終確保調用之前解鎖互斥cond.notify_all()
通過調用mtx.unlock()
之前或者使unique_lock
內碼塊的局部變量作為second
。
在類定義底部的元素變量之前放置一個private:
:,以防止它們受到外部訪問。 這將確保在不鎖定互斥鎖的情況下不能更改flag
。
有必要。
在這種情況下,您的代碼產生正確的輸出是很重要的。 這是完全有可能的是printFirst
可能不是由時間完成printSecond
被調用。 您需要互斥體來防止這種情況,並停止printSecond
和printThird
。 避免同時運行。
當first()
將1
分配給flag
時,可以同時評估second()
或third()
的flag
檢查條件。
改寫這個
cond.wait(lk, [this](){return flag==1;});
這樣,可能更容易看到:
while(!(flag==1)) cond.wait(lk);
它與帶有lambda的wait()
的作用相同。
flag
應該被讀取,而互斥舉行-但first
不約互斥和受讓人照顧flag
時,它為所欲為。 對於非原子類型,這是一場災難。 它可能工作 1000萬次(可能會)-但是當事情實際上同時發生時(因為您放任)- 繁榮 -未定義的行為
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.