SoFunction
Updated on 2025-03-05

Detailed explanation of the source code of Go channel structure and read, write and close process

  • In short, the channel maintains an accept and send queue with pointers, which contains mutex locks to ensure concurrency security, data type, number of elements, element size, channel status
  • Then read and write operations, first check whether the queue can be retrieved, then look at the buffer, and finally put it in the accept/send queue
  • Close means to wake up all goroutines and set their flag to 1, indicating that they are closed. In the future, it is nil

Structure source code

type hchan struct {
    qcount   uint           // The number of elements in the current queue    dataqsiz uint           // Buffer size, that is, the number of elements that can be cached    buf       // Point to the buffer of the queue    elemsize uint16         // Size of each element    closed   uint32         // The channel is closed.    elemtype *_type         // Types of elements in channel    sendx    uint           // The location of the next element sent    recvx    uint           // The location of the next element is received    recvq    waitq          // A goroutine queue waiting to be received    sendq    waitq          // The goroutine queue waiting to be sent    lock     mutex          // Mutex locks used to protect channel}

Send data

When a goroutine is to send data to the channel, it executeschansendFunction.

  • This function will first perform the channelAdd lock,ThenDetermine whether there is a goroutine waiting to be received
  • If there is, then send the data directly to it; otherwise, if the buffer is not full, then put the data into the buffer and add one to the number of elements in the queue;
  • If the queue is full, then add the current goroutineA goroutine queue waiting to be sentandblockIt, waiting for other goroutines to receive data.

Accept data

When a goroutine is to receive data from the channel, it executessrc/runtime/InchanrecvFunction.

  • This function will also perform channelAdd lock, and then determine whether there is a goroutine waiting to be sent, and if so, receive data directly from it;
  • Otherwise, ifBufferThe number of elements is greater than 0, thenBufferTake out an element and reduce the number of elements in the queue by one.
  • ifBufferIf empty, the current goroutine is addedA goroutine queue waiting to be receivedand block it, waiting for other goroutines to send data.

Close channel

When a goroutine is about to close the channel, it executessrc/runtime/InclosechanFunction.

  • This function will lock the channel and thenclosedSetting the flag to 1 means that the channel has been closed.
  • Then iterate over the goroutine queues waiting to be sent and waiting to be received, wake them all up, and return a special value to indicate that the channel has been closed.

This is the article about the source code of Go channel structure and the reading, writing and closing process. For more related content of go channel structure, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!