How Go Channels Work Internally (hchan, sudog)

Go channels use an hchan struct with a circular buffer and sudog wait queues to synchronize goroutines safely.

Go channels are implemented as hchan structures containing a circular buffer and two wait queues (recvq and sendq) of sudog objects that block goroutines waiting to send or receive. When a send or receive operation cannot proceed immediately, the runtime creates a sudog, links it into the appropriate queue within the hchan, and parks the goroutine until a matching operation wakes it up.

// src/runtime/chan.go
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
    recvq    waitq          // list of recv waiters (sudogs)
    sendq    waitq          // list of send waiters (sudogs)
    lock     mutex          // protects all fields
}

type waitq struct {
    first *sudog
    last  *sudog
}