web-dev-qa-db-ja.com

アクティブなゴルーチンの数を数える/表示する

キューと、デキューとエンキューの両方を行う関数があります。リストに何かがある限り、適切な量のゴルーチンがキューで動作することを確認したいと思います。

これは私が使用しているコードですが、現在アクティブなゴルーチンの量を印刷する方法があるかどうか疑問に思いました

遊び場へのリンク

var element int

func deen(queue chan int) {

    element := <-queue
    fmt.Println("element is ", element)
    if element%2 == 0 {
        fmt.Println("new element is ", element)
        queue <- (element*100 + 11)
        queue <- (element*100 + 33)
    }
}

func main() {
    queue := make(chan int, 10)
    queue <- 1
    queue <- 2
    queue <- 3
    queue <- 0 
    for len(queue) != 0 {
        for i := 0; i < 2; i++ {
            go deen(queue)
        }
    }
    fmt.Scanln()
    fmt.Println("list is has len", len(queue)) //this must be 0

}    
12
meto

runtime.NumGoroutine しかし、あなたはこれに間違って近づいています。

  1. あなたのループはゴルーチンを生み出し続けます。
  2. これにより、forループが原因でCPUサイクルが不必要に消費されます。

1つのアプローチは、sync.WaitGroupを使用することです。

func deen(wg *sync.WaitGroup, queue chan int) {
    for element := range queue {
        wg.Done()
        fmt.Println("element is ", element)
        if element%2 == 0 {
            fmt.Println("new element is ", element)
            wg.Add(2)
            queue <- (element*100 + 11)
            queue <- (element*100 + 33)
        }
    }
}

func main() {
    var wg sync.WaitGroup
    queue := make(chan int, 10)
    queue <- 1
    queue <- 2
    queue <- 3
    queue <- 0
    for i := 0; i < 4; i++ {
        wg.Add(1)
        go deen(&wg, queue)
    }
    wg.Wait()
    close(queue)
    fmt.Println("list is has len", len(queue)) //this must be 0
}

playground

9
OneOfOne