[英]Bottleneck in Threads C++
所以我只是想驗證我的理解,並希望你們能夠解決任何誤解。 所以基本上我有兩個線程使用相同的鎖並在他們持有鎖時執行計算但有趣的是在鎖內我將導致線程暫時休眠。 對於兩個線程,這兩個線程的睡眠時間會略有不同。 由於鎖的工作方式,更快的線程不會被較慢的線程瓶頸,因為它必須等待它完成?
例如:
Thread1() {
lock();
usleep(10)
lock();
}
-
Thread2() {
lock();
sleep(100)
lock();
}
現在因為Thread2持有更長的鎖,這將導致瓶頸。 而且可以肯定的是,這個系統應該在誰獲得鎖定時來回發生,對吧?
它應該是:
Thread1 gets lock
Thread1 releases lock
Thread2 gets lock
Thread2 releases lock
Thread1 gets lock
Thread1 releases lock
Thread2 gets lock
Thread2 releases lock
等等,對吧? Thread1在發布之后永遠不能獲得鎖定,可以嗎?
Thread1在發布之后永遠不能獲得鎖定,可以嗎?
不 ,線程1 可以重新獲取鎖,將其釋放之后,因為線程2仍然可以暫停 (睡覺,因為調度程序)
sleep
只能保證線程至少能夠睡到想要的數量,它可以並且通常會更多。
在實際操作中,您在計算值時不會保持鎖定,您將獲得鎖定,獲取所需的計算值,解鎖,計算它,然后再次獲取鎖定,檢查計算的舊值是否仍然有效/想要,然后存儲/返回您的計算結果。 為此,發明了std::future
和atomic數據類型。
......這個系統應該在誰獲得鎖定時來回發生,對吧?
大多數時候它會來回反復,但有些時候可能會/將會有兩個鎖定/解鎖周期。 這取決於您的調度程序,任何執行和周期可能會有所不同。
根據您要實現的目標,有幾種可能性。
如果您希望線程以特定順序運行,請查看此處 。 基本上有兩種選擇:
- 一個是使用事件,其中一個線程正在發信號通知下一個線程完成了他的工作,因此下一個線程可以啟動。
- 另一個是有一個調度程序線程來處理事件或信號量的排序。
如果你想讓你的線程獨立運行但是有一個鎖定機制,其中保留了嘗試獲取鎖定的順序,你可以看看這里 。 答案的最后一部分使用每個線程一個條件變量的隊列似乎很好。
正如之前的答案和評論中所述,使用睡眠進行調度是一個壞主意。 鎖也只是一種互斥機制,對執行順序沒有任何保證。 鎖通常用於防止對關鍵資源的並發訪問,因此它應該這樣做。 臨界區越小越好。
最后是嘗試訂購線程是制造“瓶頸”。 在這種特殊情況下,如果在鎖定的部分中進行所有計算,則線程將不會並行執行任何操作,因此您可以質疑使用線程的效用。
編輯:
只是更多的警告:小心,使用線程並不是因為在你的機器上工作了10次(按照你的意願)它總是會,特別是如果你改變任何上下文(機器,工作量......)。 你必須確保它的設計。
絕對沒有什么能阻止任何一個線程在釋放后立即重新獲得鎖定。 我不知道你的想法會阻止這種情況發生,但什么都沒有。
實際上,在許多實現中,已經運行的線程在獲取必須准備好運行的線程的鎖定方面具有優勢。 這是最小化上下文切換的合理優化。
如果您使用睡眠作為模擬工作的方式並認為這代表了鎖定公平性的一些現實世界問題,那么您錯了。 睡覺的線程是自願產生剩余的時間片,並且與處理工作時間耗盡的線程的處理方式截然不同。 如果這些線程實際上正在工作,最終一個線程將耗盡其時間片。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.