Go

Describe the runtime internals of a channel (hchan).

Question 184HardGo 1.22 to 1.25

A channel value is a pointer to a runtime.hchan struct allocated on the heap. Its main fields are:

  • qcount, dataqsiz: number of elements currently queued and buffer capacity.
  • buf: pointer to a circular array of dataqsiz elements, with sendx/recvx indices.
  • elemsize, elemtype: used to copy values in and out.
  • closed: flag.
  • recvq, sendq: FIFO linked lists (waitq) of sudogs, one per parked goroutine.
  • lock: a runtime mutex that protects all of the above.

On a send, the runtime takes the lock. If a receiver is waiting in recvq, it copies the value directly onto that goroutine's stack, skipping the buffer, and marks the goroutine runnable. Otherwise, if the buffer has room, it copies into buf[sendx]. If neither is possible, it enqueues a sudog on sendq and parks the goroutine with gopark. Receive mirrors this. When the buffer is full and a sender is waiting, a receiver takes the head of the buffer and moves the waiting sender's value into the freed slot, which keeps FIFO order.

Gotchas: since a channel is a pointer, passing it by value is cheap and every copy shares the same state. Operations are mutex-protected, not lock-free, so a heavily contended channel can cost more than a sync.Mutex or atomics.

More on Channels & select

All 38 Channels & select questions