An overview of the

Golang Channel is one of the most important tools we use to deal with coroutine communication, and its performance varies greatly in some boundary cases.

This paper makes a simple test description on the performance of sending and receiving and closing of Golang in the normal state, closed state and nil state of channel. If you have any questions, welcome to discuss.

Conclusion of channel operation in various states

Channel operation The normal state The closed position nil
send Square root X (panic: send on closed channel) X
receive Square root √ (initial value received) X
Shut down Square root X (panic: close of closed channel) X

Normal sending and receiving

The sample code

package main

import (
	"fmt"
)
func main(a) {
	ch := make(chan string)
	go send(ch)
	recv(ch)
	close(ch)       / / close
}
/ / receive
func recv(ch <-chan string) {
	x := <-ch
	fmt.Println("result:", x)
}
/ / send
func send(ch chan<- string) {
	ch <- "send_val"
}

Copy the code

Operating results: (Everything is normal)

result: send_val
Copy the code

The operation is performed on the closed channel

package main

import (
	"fmt"
	"time"
)

func main(a) {
	ch := make(chan string)
	close(ch)   // ok
	close(ch)   // panic: close of closed channel
	go send(ch) // panic: send on closed channel
	recv(ch)    // result:
	time.Sleep(time.Second)
}

func send(ch chan<- string) {
	ch <- "send_val"
}

func recv(ch <-chan string) {
	x := <-ch
	fmt.Println("result:", x)
}
Copy the code

nilChannel operation performance

  • When sending: the situation is slightly complicated, when there is no receiver, it will block, there is a receiver when the direct errorfatal error: all goroutines are asleep - deadlock!
  • Closed: Exceptionpanic: close of nil channel
  • When received: errorfatal error: all goroutines are asleep - deadlock!
package main

import (
	"fmt"
	"time"
)

func main(a) {
	var ch chan string
	close(ch)   // panic: close of nil channel
	go recv(ch) // goroutine 1 [chan receive (nil chan)]:
	send(ch)    // fatal error: all goroutines are asleep - deadlock!
	time.Sleep(time.Second)
}

func send(ch chan<- string) {
	ch <- "send_val"
}

func recv(ch <-chan string) {
	x := <-ch
	fmt.Println("result:", x)
}
Copy the code