golang goroutines,chanel和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()
}

fatal error: all goroutines are asleep – deadlock!

解决方案:

  • 问题的背景是,range操作符从通道中读取数据,直到通道关闭。因此,for-range循环一直在等待更多来自通道的输入。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
}

游乐场网址

给TA打赏
共{{data.count}}人
人已打赏
未分类

如何发送非持久性值到云火库?

2022-9-8 17:36:21

未分类

通过不同变量的不同功能创建多列。

2022-9-8 17:47:35

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索