Reputation: 47
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
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