dongmu7335 2019-01-12 08:15
浏览 129
已采纳

一个带有死锁的Go Channel的简单示例,以及为什么

My code as follows:

package main

import (
    "fmt"
)

func main() {
    c1 := make(chan int)
    fmt.Println("push c1: ")
    c1 <- 10
    g1 := <- c1
    fmt.Println("get g1: ", g1)
}

when I debug with delve, it prints this result:

push c1:
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
        D:/Go/projects/hello-world/src/ch9/code9_6/code1.go:10 +0xde
Process 6276 has exited with status 2

I don't know why, it's just one simple channel example, I make one channel, send value to it and get value from it, just this, someone can tell me why, and how to correct it, Thx a lot.

  • 写回答

2条回答 默认 最新

  • douji9816 2019-01-12 08:30
    关注

    Quote from https://tour.golang.org/concurrency/2:

    By default, sends and receives block until the other side is ready. This allows goroutines to synchronize without explicit locks or condition variables.

    Channels are meant to work between goroutines, but you have only 1. So c1 <- 10 blocks execution, until someone (usually in other goroutine) receives the value.

    To fix that:

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        c1 := make(chan int)
    
        go func() {
            g1 := <- c1 // wait for value
            fmt.Println("get g1: ", g1)
        }()
    
        fmt.Println("push c1: ")
        c1 <- 10 // send value and wait until it is received.
    }
    

    Try executing it in The Go Playground.

    I suggest you go through official Go concurrency tour starting from https://tour.golang.org/concurrency/1

    EDIT: Another option is to use Buffered channel, like below. However making Buffered channel does not mean it has non-blocking send/receive operations. It just means it will block send after N values in queue, where N is always predefined number. Internally it will store sent values into an array, and block until values are received (like non-buffered channel) when that array is filled.

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        c1 := make(chan int, 1) // buffers 1 value without blocking.
        fmt.Println("push c1: ")
        c1 <- 10
        g1 := <- c1
        fmt.Println("get g1: ", g1)
    }
    

    Try it on Go Playground.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题