0

Recently I was learning go language and wrote a piece of code, but the output is wrongfatal error: all goroutines are asleep - deadlock!

I checked a lot of information on the Internet, but couldn't find the correct solution. Has anyone encountered this problem?

my environment is $ go version go1.17.8 darwin/arm64

m1 mac, system: macOS Monterey version 12.4 (21F79)

Code:

func main() {
    A := make(chan bool)
    B := make(chan bool)
    defer close(A)
    defer close(B)
    var wg sync.WaitGroup
    wg.Add(2)

    go func() {
        for i := 0; i < 10; i += 2 {
            if <-A {
                fmt.Println(i)
                B <- true
            }
        }
        wg.Done()
    }()

    go func() {
        for i := 1; i < 10; i += 2 {
            if <-B {
                fmt.Println(i)
                A <- true
            }
        }
        wg.Done()
    }()

    A <- true
    wg.Wait()
}
Nemo
  • 1
  • 3
  • Are you familiar with the underlying theory? For example, do you understand what [deadlock](https://en.wikipedia.org/wiki/Deadlock) is? Exactly what is the question? – Karl Knechtel Jun 09 '22 at 03:18

1 Answers1

0

Looking at the code, it should be done with waitgroup, and two goroutine are executed alternately.

The problem lies in the last write of B routine to A <- true. At this time, the code that reads data from A channel has no chance to be executed. Add a simple read and it can be executed smoothly.

like it:

func main() {
    A := make(chan bool)
    B := make(chan bool)
    endch := make(chan struct{})
    defer close(A)
    defer close(B)
    defer close(endch)
    var wg sync.WaitGroup
    wg.Add(2)
    go func() {
        for i := 0; i < 10; i += 2 {
            if <-A {
                fmt.Println(i)
                B <- true
            }
        }
        wg.Done()

        endch <- struct{}{}
    }()

    go func() {
        for i := 1; i < 10; i += 2 {
            if <-B {
                fmt.Println(i)
                A <- true
            }
        }
        wg.Done()
    }()

    A <- true
    <-endch
    <-A
    wg.Wait()
}
Kan Robert
  • 259
  • 1
  • 10