为什么下面的go程序给出了死锁错误“致命错误:所有的goroutines都睡着了-死锁!”

dohp0rv5  于 2023-11-14  发布在  Go
关注(0)|答案(2)|浏览(89)

我是Golang的新手,正在尝试一些典型的使用通道的生产者消费者。我知道生产者和消费者都应该写入和读取相同的通道。但只是为了实验,我让他们写入和读取不同的通道,如下所示

package main
    
    import (
        "fmt"
        "sync"
    )
    
    func main() {
    
        var wg sync.WaitGroup
        wg.Add(2)
    
        fmt.Println("Starting the main application")
    
        channel :=make( chan int)
        channel1 :=make( chan int)
    
    
        go generateNumbersV2(&wg, channel)
        go printNumbersV2(&wg, channel1)
    
    
        fmt.Println("Waiting for other goroutines")
        wg.Wait()
        //close()
        //close(channel)
    
        fmt.Println("All goroutines finished")
    }
    
    func printNumbersV2(wg *sync.WaitGroup, rc <-chan int) {
        defer wg.Done()
    
        for idx:=0 ;idx<3;idx++ {
    
            val := <-rc
            fmt.Println("******value received from channel ",val)
        }
    }
    
    func generateNumbersV2(wg *sync.WaitGroup, wc chan<- int) {
        defer wg.Done()
    
        for idx:=0 ;idx<3;idx++ {
    
             wc<-idx
            fmt.Println("###value written to channel ",idx)
        }
    
    }

字符串
当我运行程序时,我得到下面的错误。

fatal error: all goroutines are asleep - deadlock!


现在,虽然我知道两个goroutine都被阻塞了,一个在对channel 1的读调用上,另一个在对channel 1的写调用上,所以程序永远不会终止。但我的问题是,如果实际上我在等待这些通道中的值,程序不应该无限期地等待,而不是将其声明为死锁。如果稍后,由于一些网络读/写,这些值到达,并且一些其它的Go例程写入这些通道。

lokaqttq

lokaqttq1#

只有当所有的goroutine都在同步原语上被阻塞时,一个正在运行的程序才会因为死锁而终止。如果所有的goroutine都被阻塞,等待通道操作和/或互斥锁,那么就不会有网络接收,因为没有goroutine在监听网络连接。这也意味着,在一个有很多goroutine的程序中,你可能有很多死锁的goroutine组,但是程序会继续运行。因为还有其他的goroutine可以继续前进。

9cbw7uwe

9cbw7uwe2#

generateNumbersV2正在向channel发送数据-但Go未检测到接收器。
printNumbersV2正在等待从channel1接收数据-但Go未检测到生产者。
程序将等待可能在某个时刻到达的数据,例如网络请求,这是正确的。如果您创建这样一个函数,死锁错误将消失。
一个简单的解决方案,用于说明目的:

channel: = make(chan int)

go generateNumbersV2(& wg, channel)
go printNumbersV2(& wg, channel)

字符串

相关问题