大佬们帮我看看一个协程计算的问题,报dead lock

blackdinosuar · 2019-08-28 17:52:13 · 1304 次点击 · 预计阅读时间 1 分钟 · 大约8小时之前 开始浏览    
这是一个创建于 2019-08-28 17:52:13 的文章,其中的信息可能已经有所发展或是发生改变。

func main(){
    //协程并发计算的列子同步计算
    //10000个数如果是偶数/2+1,如果是奇数*2
    write:=make(chan int ,100)
    read:=make(chan int ,200)
    singal:=make(chan bool,5) //5个信号灯为true代表5个协程都计算完毕了
    //开启一个协程写入要计算的数据
    go putChan(write)
    //开启5个协程计算
    for i:=0;i<5;i++{
        go compulate(write,read,singal)
    }
    //main函数中读取ch3如果读取到了代表计算完成了,应该关闭ch2
    for i:=0;i<5;i++{
        res:=<-singal                                                              //代码在这里报错了all goroutines are asleep - deadlock!
        fmt.Println("读取到的ch3的数据是",res)
    }
    close(singal)
    close(read) //关闭read
    //打印结果
    for v:=range read{
        fmt.Println(v)
    }
}

//一个write写入数据
func putChan(ch chan int ){
    for i:=0;i<10000;i++{
        ch<-i+1
    }
    //放完之后关闭
    close(ch)
}

//计算 偶数/2+1   奇数*2

func compulate(write chan int,read chan int ,single chan bool){
    //当前线程一直循环从chan冲读取数据
    for{
        res,ok:=<-write
        if !ok{
            break
        }
        if res%2==0{
            read<-res/2+1
        }else{
            read<-res*2
        }
    }
    //这个ch2能不能关闭-->关闭之后就不能再往里面写数据了,如果还有其他的协程在计算
    fmt.Println("有一个协程计算完毕了")
    single<-true
}

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1304 次点击  
加入收藏 微博
6 回复  |  直到 2019-09-02 14:43:54
blackdinosuar
blackdinosuar · #1 · 6年之前
    ch:=make(chan int ,5)
    go func() {
        for i:=0;i<5;i++{
            ch<-i
        }
    }()
    for i:=0;i<5;i++ {
        res:=<-ch
        fmt.Println("获取到的结果是",res)
    }

//这个代码都可以通过,^o^,为什么

blackdinosuar
blackdinosuar · #2 · 6年之前

啊 傻逼了.read满了一直阻塞了

Atao19940194
Atao19940194 · #3 · 6年之前

没看太懂.....read哪里阻塞了...大佬能说详细点吗

Atao19940194
Atao19940194 · #4 · 6年之前

是不是因为 最后才用for range去取read里的内容? read的容量只有200 10000个数还没有计算完成 通道满了就阻塞住了?

blackdinosuar
blackdinosuar · #5 · 6年之前
Atao19940194Atao19940194 #4 回复

是不是因为 最后才用for range去取read里的内容? read的容量只有200 10000个数还没有计算完成 通道满了就阻塞住了?

应该是的read太小了 ,读满了.就一直阻塞,而导致信号灯chan也放不满.这时write也写满了.所有的goroutine都阻塞了

tangname
tangname · #6 · 6年之前

你的 read 只有写没有读,假如超过200之后就会阻塞.

single<-true 永远都无法执行.

所以在执行以下代码的时候, res:=<-singal 会一直阻塞,自然就deedlock了.

 for i:=0;i<5;i++{
        res:=<-singal 
        fmt.Println("读取到的ch3的数据是",res)
    }
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传