[go] channel structure source code and process of reading, writing and closing

  • In short, the channel maintains a receiving and sending queue with pointers , which contains mutex locks to ensure concurrency security, data type, number of elements, element size, and channel status
  • Then read and write operations, first check whether the queue can be taken out, then check the buffer, and finally put it into the receive/send queue
  • Closing is to wake up all goroutines and set their flags to 1, which means they are closed, and if someone visits them in the future, they will be nil

Structure source code

type hchan struct {
    
    
    qcount   uint           // 当前队列中元素的数量
    dataqsiz uint           // 缓冲区大小,即可以缓存的元素数量
    buf      unsafe.Pointer // 指向队列的缓冲区
    elemsize uint16         // 每个元素的大小
    closed   uint32         // channel 是否已关闭的标志
    elemtype *_type         // channel 中元素的类型
    sendx    uint           // 下一次发送元素的位置
    recvx    uint           // 下一次接收元素的位置
    recvq    waitq          // 等待接收的 goroutine 队列
    sendq    waitq          // 等待发送的 goroutine 队列
    lock     mutex          // 用于保护 channel 的互斥锁
}

send data

When a goroutine wants to send data to the channel, it executes  chansend the function.

  1. This function will first lock the channel , and then determine whether there are goroutines waiting to receive
  2. If there is , send the data to it directly; otherwise, if the buffer is not full, put the data into the buffer and add one to the number of elements in the queue;
  3. If the queue is full , add the current goroutine to the queue of goroutines waiting to send , and block it, waiting for other goroutines to receive data.

accept data

When a goroutine wants to receive data from a channel, it executes  the function src/runtime/chan.go in  chanrecv .

  1. This function will also lock the channel , and then judge whether there is a goroutine waiting to be sent, and if so, receive data directly from it;
  2. Otherwise, if the number of buffer elements is greater than 0, an element is taken from the buffer and the number of elements in the queue is decremented by one.
  3. If the buffer is empty, add the current goroutine to the queue of goroutines waiting to receive , and block it, waiting for other goroutines to send data.

close channel

When a goroutine wants to close the channel, it executes  the function src/runtime/chan.go in  closechan .

  1. This function will lock the channel, and then  closed set the flag to 1, indicating that the channel has been closed.
  2. Then traverse the queue of goroutines waiting to send and wait to receive, wake them up, and return a special value to indicate that the channel has been closed.

Guess you like

Origin blog.csdn.net/csxylrf/article/details/130419871