Closing Channels
#
// Channel တစ်ခုကို _ပိတ်လိုက်ခြင်း (Closing)_ က အဲဒီ channel ပေါ်မှာ နောက်ထပ်တန်ဖိုးတွေ
// ပို့တော့မှာ မဟုတ်ဘူးဆိုတာကို ပြောလိုက်တာပါ။ ဒါက channel ကနေ လက်ခံနေသူတွေဆီကို
// ပြီးဆုံးကြောင်း အသိပေးဖို့ အသုံးဝင်ပါတယ်။
package main
import "fmt"
// ဒီဥပမာမှာ `main()` goroutine ကနေ worker goroutine ဆီကို
// လုပ်ဆောင်ရမယ့် အလုပ်တွေကို ဆက်သွယ်ပေးပို့ဖို့ `jobs` channel ကို သုံးပါမယ်။
// Worker အတွက် နောက်ထပ်အလုပ်မရှိတော့တဲ့အခါ `jobs` channel ကို `close` လုပ်ပါမယ်။
func main() {
jobs := make(chan int, 5)
done := make(chan bool)
// ဒါက worker goroutine ပါ။ သူက `jobs` ကနေ `j, more := <-jobs` နဲ့
// ထပ်ခါထပ်ခါ လက်ခံပါတယ်။ ဒီ special 2-value ပုံစံ လက်ခံမှုမှာ၊ `jobs` က
// `close` ခံထားရပြီး channel ထဲက တန်ဖိုးအားလုံး လက်ခံပြီးသွားရင်
// `more` တန်ဖိုးက `false` ဖြစ်သွားပါမယ်။ အလုပ်အားလုံး လုပ်ပြီးသွားတဲ့အခါ
// `done` ပေါ်မှာ အသိပေး (notify) ဖို့ ဒီနည်းကို သုံးပါတယ်။
go func() {
for {
j, more := <-jobs
if more {
fmt.Println("received job", j)
} else {
fmt.Println("received all jobs")
done <- true
return
}
}
}()
// ဒါက worker ဆီကို `jobs` channel ကနေ အလုပ် 3 ခု ပို့ပြီး
// နောက်ဆုံးမှာ channel ကို ပိတ်လိုက်ပါတယ်။
for j := 1; j <= 3; j++ {
jobs <- j
fmt.Println("sent job", j)
}
close(jobs)
fmt.Println("sent all jobs")
// အရင်က တွေ့ခဲ့တဲ့ [synchronization](channel-synchronization) နည်းလမ်းကို
// သုံးပြီး worker ကို စောင့်ပါတယ်။
<-done
}
$ go run closing-channels.go
sent job 1
received job 1
sent job 2
received job 2
sent job 3
received job 3
sent all jobs
received all jobs
# Channel တွေကို ပိတ်တဲ့ သဘောတရားက နောက်ဥပမာဖြစ်တဲ့
# channel တွေပေါ်မှာ `range` သုံးတာဆီကို ဦးတည်သွားပါတယ်။