加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

为什么这是golang / waitgroup的死锁?

发布时间:2020-12-16 19:04:27 所属栏目:大数据 来源:网络整理
导读:我不确定我错过了什么但是我遇到了死锁错误.我正在使用一个缓冲的通道,在完成所有程序后我将其范围覆盖.该通道的容量为4,我正在运行4个例程,所以我希望它在达到最大容量后自动“关闭”. package mainimport "fmt"import "sync"func main() { ch := make(chan
我不确定我错过了什么但是我遇到了死锁错误.我正在使用一个缓冲的通道,在完成所有程序后我将其范围覆盖.该通道的容量为4,我正在运行4个例程,所以我希望它在达到最大容量后自动“关闭”.
package main

import "fmt"
import "sync"

func main() {
    ch := make(chan []int,4)
    var m []int

    var wg sync.WaitGroup
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            ch <- m
            return
        }()
    }
    wg.Wait()

    for c := range ch {
        fmt.Printf("c is %v",c)
    }
}
你有两个问题:

>由于您的频道太小,所有goroutine都没有足够的位置:当您的频道已满时,剩余的goroutines必须等待一个插槽被释放
> range ch仍然在等待通道中的元素进入,并且没有剩余的goroutine可以写入它.

解决方案1:

使通道足够大,关闭它以使范围停止等待:

ch := make(chan []int,5)
...
wg.Wait()
close(ch)

Demonstration

这可以工作,但这主要是因为你没有在所有任务完成之前开始打印,所以这里的通道的目的就失败了.

解决方案2:
此解决方案允许实际流水线操作(即较小的通道缓冲区),在打印时执行Done():

func main() {
    ch := make(chan []int,4)
    var m []int

    var wg sync.WaitGroup
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func() {
            ch <- m
            return
        }()
    }
    go func() {
        for c := range ch {
            fmt.Printf("c is %vn",c)
            wg.Done()
        }
    }()
    wg.Wait()
}

Demonstration

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读