Home  >  Article  >  Backend Development  >  Why does the following go program give a deadlock error "Fatal error: All goroutines are sleeping - deadlock!"

Why does the following go program give a deadlock error "Fatal error: All goroutines are sleeping - deadlock!"

PHPz
PHPzforward
2024-02-09 08:00:11400browse

为什么下面的 go 程序会出现死锁错误“致命错误:所有 goroutine 都在睡眠 - 死锁!”

In the Go language, deadlock is a common error. When all goroutines are sleeping, a fatal error will occur: "Fatal error: All goroutines are sleeping. - Deadlock!". This situation usually occurs when multiple goroutines are waiting for each other. When one goroutine waits for another goroutine to complete an operation, and another goroutine waits for the first goroutine to complete an operation, a deadlock occurs. In this case, the program cannot continue to execute because all goroutines cannot continue to execute. In order to avoid deadlock errors, we need to carefully design and manage the dependencies between goroutines to ensure that they can work together correctly.

Question content

I am new to golang and am trying to use some typical producer consumers of channels. I understand that both producer and consumer should write and read from the same channel. But just for experimenting, I made them write and read from different channels as shown below

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)
        }
    
    }

When I run the program, I get the following error.

fatal error: all goroutines are asleep - deadlock!

Now, although I know that both goroutines are blocked, one on the read call to channel 1 and the other on the write call to channel, so the program never terminates. But my question is, if it is actually waiting for a value in these channels, shouldn't the program wait indefinitely instead of declaring it a deadlock? What if later due to some network read/write, the values ​​arrive and some other go routine writes to these channels?

Solution

A running program will terminate due to a deadlock panic only when all goroutines are blocked on synchronization primitives. If all goroutines are blocked waiting for channel operations and/or mutex locks, network reception is not possible because no goroutine is listening for network connections. This also means that in a program with many goroutines, you may have many groups of deadlocked goroutines, but the program still continues to run because there are other goroutines that can still continue to run.

The above is the detailed content of Why does the following go program give a deadlock error "Fatal error: All goroutines are sleeping - deadlock!". For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete