“where channel send”这个问题是关于什么问题?

huangapple go评论84阅读模式
英文:

What is the problem about where channel send

问题

这个程序的输出是:

    致命错误:所有的goroutine都处于休眠状态 - 死锁!
    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)
}
英文:

this program output:

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

But comment line 5 c &lt;- 1 and uncomment line 9 //c &lt;- 1 (or line 8 - ok this makes sense) there is no problem. Is this make sense or diffuculty of manange channels

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

答案1

得分: 0

我已经将代码的相关部分注释掉,这样就容易理解了。

package main

import "fmt"

func main() {
	c := make(chan int) // 无缓冲通道
	q := make(chan int) // 无缓冲通道
	w := make(chan int) // 无缓冲通道

	// 由于 c、q 和 w 都是无缓冲通道,所以发送操作只有在接收方准备好或最终准备好时才能进行。
	// 如果接收方无法准备好,那么就会发生死锁,因为发送操作无法进行。
	//
	// 示例:
	// c := make(chan int)
	//
	// c <- 1    // 发送
	// <-c       // 接收
	//
	// 在上面的示例中,发送操作无法进行,因为 c <- 1 是一个同步调用,即除非 c <- 1 执行完毕,否则无法继续执行下一条指令。
	// 而发送操作的条件是必须有接收方,即 <-c
	// 因此,会发生死锁。

	// 启动一个 goroutine,以便 c 准备好
	// 非阻塞的,即使 q <- <-c 没有执行,程序也可以继续执行下一条指令。
	go func() {
		q <- <-c
	}()

	// 启动一个 goroutine,以便 q 准备好
	// 非阻塞的,即使 w <- <-q 没有执行,程序也可以继续执行下一条指令。
	go func() {
		w <- <-q
	}()

	// 因此,c 已经准备好或最终准备好,因为它由一个已经启动的 goroutine 处理。
	c <- 100

	// c -> q -> w
	// 发送到 c 的值将传递到 w
	fmt.Println(<-w)
}
英文:

I have commented out the relevant parts of the code so that's understable.

package main

import &quot;fmt&quot;

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&#39;t be ready, then it&#39;s a deadlock because send
	// cannot happen.
	//
	// Example:
	// c := make(chan int)
	//
	// c &lt;- 1	// send
	// &lt;-c		// receive
	//
	// In the above example the send cannot happen as c &lt;- 1
	// is a synchronous call i.e., it cannot proceed to next instruction
	// unless c &lt;- 1 gets executed. And condition for the send to happen
	// is that their should be a receiver i.e., &lt;-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 &lt;- &lt;-c is not executed.
	go func() {
		q &lt;- &lt;-c
	}()

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

	// So, c is ready or eventually ready as it&#39;s handled by a already
	// spawned goroutine.
	c &lt;- 100

	// c -&gt; q -&gt; w
	// There value sent to c will reach w
	fmt.Println(&lt;-w)
}

huangapple
  • 本文由 发表于 2021年7月21日 22:22:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/68471255.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定