英文:
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 <- 1
and uncomment line 9 //c <- 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 <- 1
go func() { q <- <-c}()
go func() { w <- <-q}()
// go func() {c <- 1}()
//c <- 1
fmt.Println(<-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 "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)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论