Do not communicate by sharing memory; instead, share memory by communicating.

A channel is not a simple piece of shared memory. It is a data structure (hchan) that keeps track of shared memory, but also stores information that is used by the runtime scheduler for goroutines execution optimization.


The statement below creates a buffered channel capable of holding up to 3 values of type int.

// buffered channel
ch := make(chan int, 3)
 
// unbuffered channel
ch := make(chan int, 0)
ch := make(chan int)

If the channel is unbuffered, the sender blocks until the receiver has received the value

https://medium.com/@akankshadokania/why-golang-6b1f1c957dbd

==The size of the buffer we define during the channel creation could drastically impact the performances.==

The functionmake allocates an hchan struct on the heap and returns a pointer to it.

Here are some fields of the hchan struct and their explanations.

type hchan struct {
	qcount   uint           // total data in the queue
	dataqsiz uint           // size of the circular queue
	buf      unsafe.Pointer // points to an array of dataqsiz elements
	elemsize uint16
	closed   uint32
	elemtype *_type // element type
	sendx    uint   // send index
	recvx    uint   // receive index
	recvq    waitq  // list of recv waiters
	sendq    waitq  // list of send waiters
	lock mutex
}
 
type waitq struct {
 
		first *sudog
		last  *sudog
 
} // pseudo goroutine
 
type sudog struct {
 
		g     *g
		elem  unsafe.Pointer
		next  *sudog
		prev  *sudog
		...
 
		c     *hchan
 
}
  • qCount indicates the length of the data in the channel.
  • dataqsiz indicates the size of the ring queue.
  • elemsize indicates the occupancy size of the element type and is used to calculate the memory size occupied by the element of the current type.
  • buf is a pointer to an array, which maintains a **circular queue (**used only for buffered channel)
  • sendx is the index of the sent element in the array
  • recvx is the index of the received element in the array
    • sendx and recvx are used to identify the index in buf corresponding to the current channel send and receive, respectively.
  • lock ensures that the reading and writing of the channel is an atomic operation
  • recvq stores the blocked goroutines while trying to read data on the channel.
  • sendq stores the blocked goroutines while trying to send data from the channel.
    • Remember that Both of *recq* and *sendq* are linked list.
  • closed indicates whether channel has been closed.

![[Untitled 365.png|https://medium.com/@akankshadokania/why-golang-6b1f1c957dbd]]

https://levelup.gitconnected.com/how-does-golang-channel-works-6d66acd54753

https://medium.com/a-journey-with-go/go-buffered-and-unbuffered-channels-29a107c00268

https://codeburst.io/diving-deep-into-the-golang-channels-549fd4ed21a8?gi=3761456ebf80

https://www.youtube.com/watch?v=KBZlN0izeiY

https://docs.google.com/document/d/1yIAYmbvL3JxOKOjuCyon7JhW4cSv1wy5hC0ApeGMV9s/pub


🌱 Back to Garden