深入淺出多執行緒系列之十二 雙向訊號和競賽

2021-09-24 23:15:08 字數 1207 閱讀 3482

雙向訊號和競賽(two-way signaling and races)

monitor.pulse方法的乙個重要特性是它是非同步執行的,這意味著呼叫pulse方法並不會阻塞自己等待monitor.pulse返回。如果任何乙個執行緒在pulsed 物件上等待,它是不會阻塞的,換句話說,呼叫monitor.pulse對程式不會有什麼作用,你可以認為monitor.pulse方法被忽略了。

這樣pulse提供了乙個單向通訊:乙個 pulsing執行緒悄悄的向乙個waiting 執行緒傳送訊號。

pulse並不會返回乙個值來告訴你waiting執行緒是否收到訊號。

但是有時候我們需要知道waiting執行緒是否受到訊號,例如下面的例子:

class

race}}

static

void

saysomething()}}

} 期待的輸出:

wassup?

wassup?

wassup?

wassup?

wassup?

實際的輸出:

wassup? (

執行緒等待)

在saysomething方法中,for迴圈執行到while,此時_go為false,所以monitor.wait開始等待。在mainthread中,for迴圈設定_go為true。然後pulseall.但是pulseall方法是非同步的。

所以在saysomething執行緒被喚醒前,mainthread中的for迴圈可能已經執行完畢。所以saysomething方法中的第乙個wait執行緒收到訊息詞是_go為true,所以往下執行,再次將_go欄位設定為false。輸出」wassup?」,但是下次迴圈由於_go為false,所以需要再次wait.所以實際的輸出列印了乙個wassup,然後開始等待。

我們需要主線程在每一次迭代中如果worker仍然在執行上乙個任務,那麼主線程阻塞。等到worker執行完畢,那麼主線程恢復執行,然後執行迭代。

我們可以增加乙個_ready 標誌,從而控制主線程在設定_go 標誌之前worker執行緒已經ready了。也就是說主線程在設定_go之前,會等待worker完成任務,然後等待worker將ready設為true,當worker將ready設定為true後,通過pulse來通知主線程。

class

race}}

static

void

saysomething()}}

}

深入淺出多執行緒系列之三 執行緒池

執行緒池 每乙個執行緒缺省會被分配 1mb的記憶體,在 c 中,這些都是實打實的分配的,當乙個執行緒啟動的時候,為了分配臨時堆疊大約需要花費幾百微秒的時間。執行緒池通過迴圈利用執行緒可以讓你更高效的利用執行緒。執行緒池就像外包的勞務隊一樣,有任務給他們,他們會管理勞務工的一切,你不需要去花時間去找單...

深入淺出多執行緒系列之三 執行緒池

執行緒池 每乙個執行緒缺省會被分配 1mb的記憶體,在 c 中,這些都是實打實的分配的,當乙個執行緒啟動的時候,為了分配臨時堆疊大約需要花費幾百微秒的時間。執行緒池通過迴圈利用執行緒可以讓你更高效的利用執行緒。執行緒池就像外包的勞務隊一樣,有任務給他們,他們會管理勞務工的一切,你不需要去花時間去找單...

深入淺出Docker系列

深入淺出系列 深入淺出docker 一 docker核心技術預覽 深入淺出docker 二 docker命令列探秘 深入淺出docker 三 docker開源之路 深入淺出docker 四 docker的整合測試部署之道 深入淺出docker 五 基於fig搭建開發環境 原始碼分析系列 docker...