go協程控制方式有 waitGroup, select+chan(類似epoll), context三種。
waitGroup類似於消費者模型,使用ADD() 方法指定初始產品數量,使用Done()方法消費一個物品,使用Wait()表示直到物品數量消費到0爲止 ,否則一直阻塞。
select就是對管道進行選擇,哪個管道中寫入了數據就選擇哪個,多個同時寫入的話隨機選擇。
context即上下文,使用
ctx, cancel := context.WithCancel(context.Background())
ctx傳入到要監控的 協程中, cancel供控制協程使用。ctx.Done()返回一個只讀的channel。
當調用cancel()時, ctx.Done() 這一方法返回的管道就會別寫入。
代碼如下:
package main
import (
"context"
"fmt"
"time"
)
func watch(ctx context.Context, name string){
for{
select {
// 當cancel調用時 Done 返回一個struct{}
case <- ctx.Done():
fmt.Println("exit watch")
return
default:
// print format
fmt.Printf("%s is watching\n", name)
time.Sleep(2*time.Second)
}
}
}
func main(){
ctx, cancel := context.WithCancel(context.Background())
// cancel 是個函數 ctx 是傳到調用函數中的 cancel是在哪裏取消哪裏調用
// 用來控制多個協程的一種方式
go watch(ctx, "watch 1")
go watch(ctx, "watch 2")
go watch(ctx, "watch 3")
time.Sleep(10*time.Second)
fmt.Println("stop watching")
cancel()
}