The problem
What happens when I read and write to an uninitialized chan? Why is that?
How to answer
Reading and writing uninitialized Chan blocks.
For example,
1. Write uninitialized chan
package main
// Write uninitialized chan
func main(a) {
var c chan int
c <- 1
} Copy the code
// Output the result
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send (nil chan)]:
main.main()
/Users/admin18/go/src/repos/main.go:6 +0x36 Copy the code
Notice this chan send (nil chan), which we’ll talk about in a second.
2. Write and read uninitialized chan
package main
import "fmt"
// Read uninitialized chan
func main(a) {
var c chan int
num, ok := <-c fmt.Printf(Num =%v, ok=%v\n, num, ok) } Copy the code
// Output the result
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive (nil chan)]:
main.main()
/Users/admin18/go/src/repos/main.go:6 +0x46 Copy the code
Notice this chan receive (nil chan), which we’ll talk about in a second.
Ask more
There are many interview questions about Chan, and this is one of the more common ones. But one more question: why does it block on uninitialized chan?
1. For writing
/ / in the SRC/runtime/chan. Go
func chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool {
if c == nil {
// Cannot block. Return false to indicate that the message was not sent successfully
if! block { return false } gopark(nil.nil, waitReasonChanSendNilChan, traceEvGoStop, 2) throw("unreachable") } // omit other logic } Copy the code
- Uninitialized
chan
This is going to be equal tonil
When it cannot block, return directlyfalse
, said writechan
failure - when
chan
If it can block, block directlygopark(nil, nil, waitReasonChanSendNilChan, traceEvGoStop, 2)
And then callthrow(s string)
Throws an error wherewaitReasonChanSendNilChan
That’s the error I just mentioned"chan send (nil chan)"
2. For reading
/ / in the SRC/runtime/chan. Go
func chanrecv(c *hchan, ep unsafe.Pointer, block bool) (selected, received bool) {
// omit logic...
if c == nil {
if! block { return } gopark(nil.nil, waitReasonChanReceiveNilChan, traceEvGoStop, 2) throw("unreachable") } // omit logic... } Copy the code
- Uninitialized
chan
This is going to be equal tonil
When it cannot block, return directlyfalse
Read, saidchan
failure - when
chan
If it can block, block directlygopark(nil, nil, waitReasonChanReceiveNilChan, traceEvGoStop, 2)
And then callthrow(s string)
Throws an error wherewaitReasonChanReceiveNilChan
That’s the error I just mentioned"chan receive (nil chan)"
Article recommendation:
- Golang interview question: How do reflect get field tag? Why can’t json packages export tags for private variables?
- Golang: What happens to json package variables without tags?
- Golang interview question: How to avoid memory escape?
- Golang interview question: What about memory escape?
- Golang: Does memory copy happen when a string is converted into a byte array?
- Golang interview question: Flip contains
Chinese characters, numbers and English letters
The string - Golang: Is it necessarily more expensive to copy a large slice than a small one?
- Golang: What’s the difference between uintptr and unsafe.Pointer?
If you want to study one point of knowledge every day?
This article is formatted using MDNICE