Тест · Горутины и каналы · урок 3 из 13Тест — WaitGroupЧто такое sync.WaitGroup и каков контракт Add/Done/Wait?[A]sync.WaitGroup ждёт завершения набора горутин. Он хранит счётчик, который Add(n) поднимает до оператора go, а Done() опускает внутри каждой горутины; Wait() блокируется, пока счётчик не дойдёт до нуля. Группу можно передать в каждую горутину по значению: каждая копия делит счётчик с оригиналом, поэтому Done на копии уменьшает тот счётчик, за которым следит Wait, так же как через указатель.[B]sync.WaitGroup ждёт завершения набора горутин. Он хранит счётчик: вызовите Add(n) перед запуском горутин, чтобы поднять его, вызовите Done() (обычно через defer) внутри каждой горутины, чтобы уменьшить на единицу, и вызовите Wait(), чтобы заблокироваться, пока счётчик не дойдёт до нуля. Ключевое правило — вызывать Add в запускающей горутине до оператора go, а не внутри новой горутины, иначе Wait может вернуться слишком рано.[C]sync.WaitGroup ждёт завершения набора горутин. Он хранит счётчик: Add(n) поднимает его, Done() (обычно через defer) уменьшает на единицу, а Wait() блокируется, пока счётчик не дойдёт до нуля. Вызов Add можно ставить первой строкой внутри каждой новой горутины: Wait перепроверяет счётчик при каждом его изменении, поэтому не вернётся раньше, чем выполнится этот Add, даже если горутина запустилась поздно.[D]sync.WaitGroup ждёт завершения набора горутин. Он хранит счётчик: вызовите Add(n) до оператора go, вызовите Done() внутри каждой горутины и вызовите Wait(), чтобы заблокироваться, пока счётчик не дойдёт до нуля. Лишние вызовы Done безвредны: когда счётчик уже равен нулю, следующий Done оставляет его нулём, поэтому Done чаще, чем Add, программу не меняет. Так же молча пропускается и Done, для которого вообще не было парного Add.Подпишись, чтобы пройти курсКурс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.Продолжить с TelegramВойти другим способом← Назадsync.WaitGroupДалее →Каналы