Метод sync.WaitGroup.Done
Метод sync.WaitGroup.Done уменьшает внутренний счетчик
структуры WaitGroup на единицу. Он вызывается внутри
горутины для того, чтобы сообщить, что она завершила свою работу.
Как правило, метод вызывается с помощью ключевого слова defer,
чтобы гарантировать уменьшение счетчика даже в случае паники.
Метод не принимает никаких параметров и не возвращает значений.
Синтаксис
wg.Done()
Пример
Давайте создадим группу ожидания, запустим две горутины
и уменьшим счетчик с помощью Done после завершения
каждой из них:
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
time.Sleep(100 * time.Millisecond)
fmt.Println("goroutine 1 done")
}()
go func() {
defer wg.Done()
time.Sleep(50 * time.Millisecond)
fmt.Println("goroutine 2 done")
}()
wg.Wait()
fmt.Println("all goroutines done")
}
Результат выполнения кода:
"goroutine 2 done"
"goroutine 1 done"
"all goroutines done"
Пример
Если горутина завершается с паникой, defer гарантирует,
что Done все равно будет вызван. В этом примере
счетчик будет уменьшен, несмотря на панику:
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
panic("something went wrong")
}()
wg.Wait()
fmt.Println("wait finished")
}
Результат выполнения кода:
"wait finished"
Пример
Метод Done можно вызвать явно без defer,
но важно убедиться, что он будет выполнен в любом случае:
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
wg.Add(3)
for i := 0; i < 3; i++ {
go func(id int) {
fmt.Printf("goroutine %d done\n", id)
wg.Done()
}(i)
}
wg.Wait()
fmt.Println("all done")
}
Результат выполнения кода:
"goroutine 2 done"
"goroutine 0 done"
"goroutine 1 done"
"all done"
Смотрите также
-
метод
sync.WaitGroup.Add,
который увеличивает счетчик ожидания -
метод
sync.WaitGroup.Wait,
который блокирует выполнение до обнуления счетчика -
саму структуру
sync.WaitGroup,
которая используется для ожидания завершения горутин -
примитив синхронизации
sync.Mutex,
который защищает общие данные от конкурентного доступа