Goroutine အများကြီး ပြီးဆုံးတာကို စောင့်ဆိုင်းဖို့ wait group ကို သုံးနိုင်ပါတယ်။ |
|
package main |
|
import ( "fmt" "sync" "time" ) |
|
ဒါက goroutine တိုင်းမှာ run မယ့် function ပါ။ |
func worker(id int) { fmt.Printf("Worker %d starting\n", id) |
expensive ဖြစ်တဲ့ အလုပ်တစ်ခုလိုမျိုးဖြစ်ဖို့ simulate လုပ်ပီး slepp လုပ်ခိုင်းထားပါတယ်။ |
time.Sleep(time.Second) fmt.Printf("Worker %d done\n", id) } |
func main() { |
|
ဒီ WaitGroup ကို ဒီမှာ စတင်လိုက်တဲ့ goroutine အားလုံး ပြီးဆုံးတာကို စောင့်ဆိုင်းဖို့ သုံးပါတယ်။ မှတ်ချက်: WaitGroup ကို function တွေဆီ တိုက်ရိုက်ပေးပို့မယ်ဆိုရင် pointer နဲ့ ပို့သင့်ပါတယ်။ |
var wg sync.WaitGroup |
Goroutine အများကြီးကို စတင်ပြီး WaitGroup ရဲ့ counter ကို တစ်ခုချင်းစီ တိုးလိုက်ပါမယ်။ |
for i := 1; i <= 5; i++ { wg.Add(1) |
Goroutine closure တိုင်းမှာ တူညီတဲ့ |
i := i |
Worker ခေါ်တာကို closure တစ်ခုနဲ့ wrap ထားဖြင့် ဒီ closure က ဒီ worker ပြီးဆုံးကြောင်းကို WaitGroup ကို အသိပေးပါတယ်။ ဒီနည်းနဲ့ worker ကိုယ်တိုင်က သူ့ကို run တဲ့ concurrency primitive တွေအကြောင်း သိစရာမလိုတော့ပါဘူး။ |
go func() { defer wg.Done() worker(i) }() } |
WaitGroup counter က 0 ပြန်ဖြစ်တဲ့အထိ block လုပ်ထားပါတယ်။ Worker အားလုံးက သူတို့ပြီးဆုံးကြောင်း အသိပေးတဲ့အထိစောင့်မှာပါ။ |
wg.Wait() |
မှတ်ချက်: ဒီနည်းလမ်းက worker တွေကနေ error တွေကို ပြန်ပို့ဖို့ straightforward မဖြစ်ပါဘူး။ ပိုပြီးအဆင့်မြင့်တဲ့ use case တွေအတွက်ဆိုရင် errgroup package ကို consider လုပ်ပါ။ |
}
|
$ 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 |
|
Worker တွေ စတင်တဲ့အစီအစဉ်နဲ့ ပြီးဆုံးတဲ့အစီအစဉ်က ပရိုဂရမ်ကို run တိုင်း ကွာခြားနိုင်ပါတယ်။ |
နောက်ဥပမာ: Rate Limiting.