2017-08-26 42 views
3
var condition bool 
var wg sync.WaitGroup 
for _, item := range items { 
    wg.Add(1) 
    go func(item) { 
     if meetsCondition(item) { 
      condition = true 
     } 
     wg.Done() 
    }(item) 
} 
wg.Wait() 
// is it safe to check condition here? 

這裏有一個討論這個問題的舊論壇: https://groups.google.com/forum/#!topic/golang-nuts/5oHzhzXCcmM答案是肯定的,它是安全的。然後討論離題使用原子等,這不是我想問的。在這種情況下WaitGroup.Wait()意味着內存屏障嗎?

在規範中甚至沒有提及WaitGroup,它的文檔是說WaitGroup.Wait:「等待塊,直到WaitGroup計數器爲零。」 沒有設置任何發生之前的關係(或做它?)。

這是否意味着第一個答案「wg.Wait返回後檢查條件是否安全」是非官方的?如果它是官方的,我失蹤的原因是什麼?非常感謝,如果你回答。

更新: 這是@ peterSO的@ ravi的答案後更新。謝謝。

好吧,如果您選擇的項目數> 1,顯然可能會出現競爭狀況。提示:條件只能設置爲true。不過,我也有同樣的問題。

,也許,我應該指出:

  1. 的底層架構只能是86,64或ARM
  2. 項目數可以在1

更新2 我當產品數量== 1時,創建後續問題: Can you make this 'incorrectly synchronized' test fail?

回答

0

那麼,在wg.Wait(),之後檢查condition是絕對安全的,您應該使用互斥鎖來保護condition,以避免它被多個go例程同時「寫入」。這就是爲什麼@peterSO在他的代碼中設置了第二十行的競賽條件b'cos,這是設置condition = true多個去程序試圖同時設置condition。這裏有一個示例https://play.golang.org/p/o3v6s_2qsY,帶有20k條rountines。

作爲一個我推薦的最佳實踐,我們在去程序函數的開始處增加了defer wg.Done(),這樣即使有返回語句,wg.Done()仍然會被調用。

1

是的。 wg.Wait()wg.Done()之間存在關係。這個簡單的事實是出於文檔中未提及的任何原因或去MM #7948。感謝伊恩蘭斯泰勒澄清它golang-nuts/5oHzhzXCcmM。關於競爭條件,您可以在同一個線索中閱讀更多內容。

有點令人失望的是,在一種自稱爲併發的語言中,人們必須依賴一個「好詞」來做基本的東西(右)。

相關問題