【问题标题】:What is the problem about where channel send通道发送到哪里有什么问题
【发布时间】:2021-09-28 22:23:28
【问题描述】:

这个程序输出:

    fatal error: all goroutines are asleep - deadlock!
    goroutine 1 [chan send]:
    main.main()
    /home/user/go/src/examples/run/chan1.go:51 +0xa9

但是注释第 5 行 c <- 1 和取消注释第 9 行 //c <- 1(或第 8 行 - 好的,这很有意义)没有问题。这是管理渠道的意义还是困难

func main() {
    c := make(chan int)
    q := make(chan int)
    w := make(chan int)
    c <- 1
    go func() { q <- <-c}()
    go func() { w <- <-q}()
    // go func() {c <- 1}()
    //c <- 1
    fmt.Println(<-w)
}

【问题讨论】:

  • c &lt;- 1 阻塞,直到从c 接收到某些东西,但是由于还没有初始化从c 接收它,它将永远阻塞,即第 6 行及以上的行将不会被执行。
  • fmt.Println(&lt;-w) 执行
  • 不,doesn'tc &lt;- 1 执行后什么都没有。
  • API server listening at: 127.0.0.1:21797 1 Process exiting with code: 0 1 来自哪里
  • @ebasruh 显示的代码不会打印该输出。

标签: go channels


【解决方案1】:

我已经注释掉了代码的相关部分,所以它是不稳定的。

package main

import "fmt"

func main() {
    c := make(chan int) // unbuffered channel
    q := make(chan int) // unbuffered channel
    w := make(chan int) // unbuffered channel

    // As c, q and w are unbuffered: so for a send to happen,
    // receiver must be ready or eventually ready. If somehow the
    // receiver can't be ready, then it's a deadlock because send
    // cannot happen.
    //
    // Example:
    // c := make(chan int)
    //
    // c <- 1   // send
    // <-c      // receive
    //
    // In the above example the send cannot happen as c <- 1
    // is a synchronous call i.e., it cannot proceed to next instruction
    // unless c <- 1 gets executed. And condition for the send to happen
    // is that their should be a receiver i.e., <-c
    // Hence, a deadlock

    // Spawn a goroutine so that c is ready
    // Non-blocking i.e., program can proceed to next instruction
    // even if q <- <-c is not executed.
    go func() {
        q <- <-c
    }()

    // Spawn a goroutine so that q is ready
    // Non-blocking i.e., program can proceed to next instruction
    // even if w <- <-q is not executed.
    go func() {
        w <- <-q
    }()

    // So, c is ready or eventually ready as it's handled by a already
    // spawned goroutine.
    c <- 100

    // c -> q -> w
    // There value sent to c will reach w
    fmt.Println(<-w)
}

【讨论】:

  • 感谢 xdsarkar。我认为必须在这方面做更多的工作
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-03
相关资源
最近更新 更多