首页 文章

goroutines死锁,需要一些解释

提问于
浏览
1

我想了解Go例程如何在这里工作 .

问题1:go-routine是否从主GO例程/ func继承任何东西?

问题2:还想知道我是否将“hi whats up”发送到msg Channels 中为什么没有收到LINE的常规例程:13 ????

1 package main
  2 
  3 import "fmt"
  4 
  5 func main() {
  6     msg := make(chan string, 2) //channel (bidirectional channel) of type string
  7 
  8     msg <- "hi whats up"
  9     fmt.Println("*****I am main go routine*****")
 10 
 11     go func() {
 12         fmt.Println("*****HI ABHI *****\n")
 13         temp := <-msg
 14         fmt.Println(temp)
 15         msg <- "Hello from a goroutine!" //send a string through the channel
 16     }()
 17 
 18     fmt.Println("Main routine waiting for message")
 19 
 20     fmt.Println(<-msg) //receive the string from the channel
 21     fmt.Println(<-msg)
 22 }

获得以下错误:

*我是主要的常规主要例程等待消息你好了什么 HI ABHI *****致命错误:所有goroutines都睡着了 - 死锁! goroutine 1 [chan receive]:main.main()/Users//work/go/src/github.com/Golang_play/goroutine/goroutine.go:21 0x1e6 goroutine 5 [chan receive]:main.main.func1(0xc420054060 )/Users/work/go/src/github.com/Golang_play/goroutine/goroutine.go:13 0x98由main.main /Users/work/go/src/github.com/Golang_play/goroutine/goroutine.go创建: 11 0xe2退出状态2

同样在以下程序中,LINE 14从不打印 .

5 func main() {
  6     msg := make(chan string, 2) //channel (bidirectional channel) of type string
  7 
  8     msg <- "hi whats up"
  9     fmt.Println("*****I am main go routine*****")
 10 
 11     go func() {
 12         fmt.Println("*****HI ABHI *****\n")
 13         temp := <-msg
 14         fmt.Println(temp)
 15         //msg <- "Hello from a goroutine!" //send a string through the channel
 16     }()

3 回答

  • 3

    您're trying to send messages two ways on the same channel, and you don' t做任何事情来保证谁读取哪些消息 . 在 func goroutine试图从 Channels 读取之前,主goroutine完全可以接收 the message it sent . 如果发生这种情况,两个goroutines都会等待永远不会到达的消息 .

    使用两个 Channels .

  • 1

    新启动的goroutine可以通过闭包从外部代码中捕获变量,但不会继承任何东西 .

    在第13行的通道接收和第20行的通道之间存在竞争 . 如果第20行的读取首先被执行,它将消耗通道上的唯一值,并且最终,两个goroutine被阻止从通道读取,因此死锁错误 . 如果你想从goroutine中获取一个值,那么最好有另一个通道,而不是尝试对它进行排序 .

  • 1

    这是一个有效的例子:

    package main
    
    import "fmt"
    
    func main() {
        msg := make(chan string)
        go func() {
            temp := <-msg
            fmt.Println(temp)
            msg <- "Hello from a goroutine!"
        }()
    
        msg <- "hi whats up"
        fmt.Println(<-msg)
    }
    

    对于无缓冲的通道,消息传递是同步的,因此goroutines永远不会从它们自己接收消息(因为相同的goroutine必须同时发送和接收才能发生这种情况) . 请注意,此设计要求您在将任何内容写入之前从 msg Channels 开始goroutine读取,否则您将无法等待读取器而无法启动它 .

相关问题