簡體   English   中英

golang goroutines, chanel 和 sync.WaitGroup

[英]golang goroutines, chanel and sync.WaitGroup

我使用簡單的代碼,但我總是陷入僵局。 請向初學者解釋我做錯了什么。

package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup

    ok := make(chan int, 3)
    for i := 0; i < 2; i++ {
        wg.Add(1)

        go func(i int, wg *sync.WaitGroup) {
            for x := range ok {
                fmt.Println(i, x)
                if x >= 5 {
                    ok <- x - 1
                }
            }
            wg.Done()
        }(i, &wg)
    }

    ok <- 1
    ok <- 3
    ok <- 2
    ok <- 5
    ok <- 3
    ok <- 9

    wg.Wait()
}

致命錯誤:所有 goroutine 都處於休眠狀態 - 死鎖!

  • 問題的背景是范圍運算符從通道中讀取,直到通道關閉。 因此,for- ok循環會繼續等待來自通道的更多輸入,即使在某個時刻沒有更多輸入出現。 同時wg.Wait()正在等待 goroutines 完成。 因此陷入僵局!

  • 要么您必須在某個時候關閉ok通道,此時通道ok沒有更多傳入值。

或者您可以像使用工作池一樣,

package main

import (
    "fmt"
    "strconv"
    "sync"
)

func worker(wg *sync.WaitGroup, ch chan string, i int) {
    defer wg.Done()
    ch <- "worker process value  " + strconv.Itoa(i)
}

func workerMonitor(wg *sync.WaitGroup, ch chan string) {
    wg.Wait()
    close(ch)
}

func doWork(ch <-chan string, done chan<- bool) {
    for i := range ch {
        fmt.Println(i)
    }
    done <- true
}

func main() {
    var wg sync.WaitGroup
    ch := make(chan string)
    var arr = [6]int{1, 3, 2, 5, 3, 9}
    for i := 0; i < len(arr); i++ {
        wg.Add(1)
        if arr[i] >= 5 {
            for j := arr[i]; j >= 5; j-- {
                wg.Add(1)
                go worker(&wg, ch, j-1)
            }
        }
        go worker(&wg, ch, arr[i])
    }

    go workerMonitor(&wg, ch)

    done := make(chan bool, 1)
    go doWork(ch, done)
    <-done
}

游樂場 url

暫無
暫無

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

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