WaitGroup is a concurrency primitive often used in Golang concurrent programming for task scheduling. It looks like it has only a few simple methods and is relatively easy to use. The internal implementation of WaitGroup has been changed several times, mainly to optimize the atomic operations of its fields.
The earliest implementation of
WaitGroup is as follows.
The meaning of its implementation fields is clearer, but it is still slightly rough; for example, sema is implemented using pointers.
Then the fields
waiters are merged. To guarantee 8-bit alignment for 64bit atomic operations, the alignment point of state1 needs to be found. sema removes the pointer implementation.
WaitGroup was implemented as follows and stabilized.
The state1 and sema fields are combined into a single field
state1, which is an array of uint32, four bytes. So either the first element is 8byte aligned, or the second element is 8byte aligned. Find the aligned 8byte, the remaining 4byte as sema.
There is no problem with this implementation, it’s just a bit roundabout. Because you have to check the alignment of state1 to determine which is the counters and waiters, which is sema.
A question: What is the maximum number of waiters in a WaitGroup?
In Go 1.18, WaitGroup has been changed again to ensure that fields of type uint64 are aligned to 8byte for 64bit architecture environments.