2016-01-03 34 views
0

從以下獲得:
包裝蛋糕接受:草莓蛋糕
包裝蛋糕接受:草莓蛋糕
包裝蛋糕接受:草莓蛋糕
包裝收到蛋糕:草莓蛋糕
我們完成了!
包裝收到蛋糕:草莓蛋糕
sync.WaitGroup - 爲什麼一氣呵成程序來後.wait()

我沒想到「我們完成了!」是第二最後?

package main 

import (
    "fmt" 
    // "strconv" 
    // "time" 
    "sync" 
) 

func makeCakeAndSend(cs chan string, wg *sync.WaitGroup) { 
    cakeName := "Strawberry Cake " 
    cs <- cakeName 
    wg.Done() 
} 

func receiveCakeAndPack(cs chan string) { 
    for s := range cs { 
     fmt.Println("Packing received cake: ", s) 
    } 
} 

func main() { 
    var wg sync.WaitGroup 
    cs := make(chan string) 

    wg.Add(5) 

    for i := 1; i <= 5; i++ { 
     go makeCakeAndSend(cs, &wg) 
    } 

    // go receiveCakeAndPack(cs) 

    go func() { 
     for s := range cs { 
      fmt.Println("Packing received cake: ", s) 
     } 
     close(cs) 
    }() 

    wg.Wait() 

    fmt.Println("We are done!") 

    var input string 
    fmt.Scanln(&input) 
} 

回答

4

這是完全正常的。 wg.Wait()確保所有的goroutines在我們繼續之前完成發送數據到頻道,它不會同步「包裝蛋糕」的打印。

當每個人都發送完數據下降通道,通道中有一個項目,對不對?但等待組已完成。

所以,你必須在主夠程繼續「我們已經完成」,並接收夠程接收並打印的競爭條件。這是不同步的,你不能保證哪一個會先發生。

+0

如果我需要從所有使用值走程序,然後再繼續 - 完成發送VS完成接收。你知道嗎? –

+1

然後您可以在wg.Wait之後關閉頻道,並且接收循環將退出。 –

+0

您也可以移動'wg.Done()':如果在將項目發佈到頻道時沒有完成,但實際處理完畢後,您應該在匿名頻道消費者中調用wg.Done()打印'收到蛋糕'後)。 – Guildencrantz

相關問題