Go با مثال: WaitGroupها

برای منتظر ماندن تا پایان کار چند گوروتین، می‌توانیم از یک wait group استفاده کنیم.

package main
import (
    "fmt"
    "sync"
    "time"
)

این تابعی است که در هر گوروتین اجرا می‌کنیم.

func worker(id int) {
    fmt.Printf("Worker %d starting\n", id)

برای شبیه‌سازی یک کار سنگین کمی صبر می‌کنیم.

    time.Sleep(time.Second)
    fmt.Printf("Worker %d done\n", id)
}
func main() {

از این WaitGroup برای منتظر ماندن تا پایان همهٔ گوروتین‌هایی که اینجا راه می‌اندازیم استفاده می‌شود. توجه: اگر WaitGroup صریحاً به توابع داده شود، باید با اشاره‌گر باشد.

    var wg sync.WaitGroup

با WaitGroup.Go چند گوروتین راه می‌اندازیم.

    for i := 1; i <= 5; i++ {
        wg.Go(func() {
            worker(i)
        })
    }

تا وقتی همهٔ گوروتین‌هایی که wg راه انداخته تمام نشده‌اند، مسدود می‌مانیم. یک گوروتین وقتی تمام می‌شود که تابعی که صدا زده برگردد.

    wg.Wait()

توجه کنید که این روش راه سرراستی برای انتقال خطاها از کارگرها ندارد. برای کاربردهای پیشرفته‌تر، استفاده از بستهٔ errgroup را در نظر بگیرید.

}
$ go run waitgroups.go
Worker 5 starting
Worker 3 starting
Worker 4 starting
Worker 1 starting
Worker 2 starting
Worker 4 done
Worker 1 done
Worker 2 done
Worker 5 done
Worker 3 done

ترتیب شروع و پایان کار کارگرها احتمالاً در هر بار اجرا متفاوت خواهد بود.

مثال بعدی: .