簡體   English   中英

Golang 頻道缺少一些值

[英]Golang channel missing some values

我有以下代碼

package main

import (
    "fmt"
    "math/rand"
    "time"
)

func main() {
    concurrent := 12
    ch := make(chan int)
    defer close(ch)
    for i := 1; i <= concurrent; i++ {
        go worker(i, ch)
    }
    for i := 1; i <= 21; i++ {
        ch <- i
    }
}

func worker(worker int, ch chan int) {
    for requestId := range ch {
        fmt.Printf("worker %d is requesting to %d...\n", worker, requestId)
        time.Sleep(time.Duration(rand.Intn(3)) * time.Second)
    }
}

main function 啟動多個運行worker function 的 goroutine,然后將一些值放入通道中,這些值由 worker 打印。 我的問題是有時通道中的最后一個值甚至更多值不是由工作人員打印的。

worker 10 is requesting to 10...
worker 5 is requesting to 1...
worker 5 is requesting to 13...
worker 7 is requesting to 6...
worker 2 is requesting to 2...
worker 3 is requesting to 7...
worker 3 is requesting to 14...
worker 6 is requesting to 4...
worker 11 is requesting to 9...
worker 9 is requesting to 8...
worker 9 is requesting to 15...
worker 12 is requesting to 11...
worker 8 is requesting to 12...
worker 8 is requesting to 16...
worker 4 is requesting to 5...
worker 1 is requesting to 3...
worker 11 is requesting to 17...

我認為這是因為主要的 function 結束並在打印最后一個值之前“殺死”所有正在運行的 goroutine,因為最后總是打印所有值。

func main() {
    concurrent := 12
    ch := make(chan int)
    defer close(ch)
    for i := 1; i <= concurrent; i++ {
        go worker(i, ch)
    }
    for i := 1; i <= 21; i++ {
        ch <- i
    }
    time.Sleep(3 * time.Second)
}

我怎樣才能在不使用睡眠的情況下解決這個問題,並且盡可能只使用頻道?

因為主 goroutine 在最后一個導致整個程序退出的for循環之后立即退出,所以后台 goroutine 可能會或可能不會有機會運行,您必須提供一些同步方式來“等待”所有工作 goroutines結束。

使用sync.WaitGroup

   func main() {

    concurrent := 12
    ch := make(chan int)

    var wg sync.WaitGroup
    for i := 1; i <= concurrent; i++ {
        wg.Add(1)
        go func(i int) {
            defer wg.Done()
            worker(i, ch)
        }(i) // You have to pass i as parameter
    }
    for i := 1; i <= 21; i++ {
        ch <- i
    }
    close(ch) // Close channel to tell all workers to stop

    wg.Wait() // Wait all workers to finish its work
   }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM