简体   繁体   中英

deadlock on not buffered channel

I'm currently following the tour of go tutorial and got to the section on channels, as I was doing some testing I found an weird behavior I'm struggling to understand

the following code produces a deadlock error

package main

import "fmt"

func main() {
    c := make(chan string)
    c <- "test"
    fmt.Printf("%v", <- c)
}

but doing one of the following things fixes the code

using a buffered channel:

package main

import "fmt"

func main() {
    c := make(chan string, 1)
    c <- "test"
    fmt.Printf("%v", <- c)
}

or setting the value to the channel on a different thread

package main

import "fmt"

func main() {
    c := make(chan string)
    go func(){c <- "test"}()
    fmt.Printf("%v", <- c)
}

what is the underlying reason for the first version of the code to produce a deadlock?

Writing to an unbuffered channel will only succeed if there is another goroutine that reads from that channel. In the first case, you have only one goroutine, the main goroutine, that writes to an unbuffered channel, and there is no other goroutine that can read from it, so it is a deadlock.

The second one works, because the channel is buffered, and writing succeeds by filling the buffer. A second write without a read will deadlock.

The third one works, because write happens in a separate goroutine, which waits until the read in the first goroutine runs.

Since the channel has no buffer, c <- "test" will block until something reads from c. Since the reader comes after the write it will never reach the read and deadlock.

If the channel has a buffer, c <- "test" writes to the buffer and does not have to wait for a reader. The reader then reads from the channel buffer.

This is all because the reader and writer are in the same goroutine and so must execute one statement after the other. If the reader and writer were in different goroutines, the writer goroutine can block until the reader goroutine reads. Because of this, buffers are often unnecessary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM