Stefan Hristov
Stefan Hristov

Reputation: 47

Why is deadlock posssible here?

I am currently learning about deadlocks in Go and when they can appear. I am viewing this code. I know a deadlock is possible here, but I cannot find it. Can someone please explain it to me?

package main

import "fmt"

func reuters(ch chan string) {
    ch <- "REUTERS"
}
func bloomberg(ch chan string) {
    ch <- "BLOOMBERG"
}
func newsReader(reutersCh chan string, bloombergCh chan string) {
    ch := make(chan string, 5)
    go func() {
        ch <- (<-reutersCh)
    }()
    go func() {
        ch <- (<-bloombergCh)
    }()
    x := <-ch
    fmt.Printf("got news from %s \n", x)
}
func main() {
    reutersCh := make(chan string)
    bloombergCh := make(chan string)
    go reuters(reutersCh)
    go bloomberg(bloombergCh)
    newsReader(reutersCh, bloombergCh)
    newsReader(reutersCh, bloombergCh)
}

Upvotes: 0

Views: 100

Answers (1)

nilskch
nilskch

Reputation: 426

When you want to read from an empty channel, the channel blocks. After running:

go reuters(reutersCh)
go bloomberg(bloombergCh)

there will be one item in reutersCh and one item in bloombergCh. When you run

newsReader(reutersCh, bloombergCh)

you start two routines that read from both channels. It is very likely, that they finish before

newsReader(reutersCh, bloombergCh)

runs a second time. In this case, reutersCh and bloombergCh are empty, so der is no way you can read from them. When you can't read from these channels, you also can't write to the local channel ch in the newsReader function. When you can't write to the channel ch you can't read from the channel and therefore it blocks.

In conclusion, you write in reutersCh and bloombergCh once and try to read from them twice. Two routines will block for sure and when the two routines from the second call of newsReader block (which is very likely), your program will block completely.

Upvotes: 2

Related Questions