go提供了sync包和channel來解決協(xié)程同步和通訊。
sync.WaitGroup是等待一組協(xié)程結(jié)束,sync.WaitGroup只有3個方法,Add()添加一個計數(shù),Done()減去一個計數(shù),Wait()阻塞直到所有任務(wù)完成。
package main import ( "fmt" "sync" "time" ) var wg sync.WaitGroup //定義一個同步等待的組 func task(i int){ fmt.Println("task...",i) //耗時操作任務(wù),網(wǎng)絡(luò)請求,讀取文件 time.Sleep(time.Second) wg.Done() //減去一個計數(shù) } func main(){ for i:= 0;i10;i++{ wg.Add(1) //添加一個計數(shù) go task(i) } wg.Wait() //阻塞直到所有任務(wù)完成 fmt.Println("over") }
運行結(jié)果:
task... 9
task... 4
task... 6
task... 0
task... 7
task... 5
task... 1
task... 2
task... 8
task... 3
over
利用緩沖信道channel協(xié)程之間通訊,其阻塞等待功能實現(xiàn)等待一組協(xié)程結(jié)束,不能保證其goroutine按照順序執(zhí)行
package main import ( "fmt" ) var ch = make(chan int,10) func task(i int){ fmt.Println("task...",i) ch - i } func main(){ for i:= 0;i10;i++{ go task(i) } for i:= 0;i10;i++{ - ch } fmt.Println("over") }
運行結(jié)果:
task... 9
task... 0
task... 1
task... 2
task... 6
task... 7
task... 3
task... 4
task... 8
task... 5
over
利用無緩沖的信道channel協(xié)程之間通訊,其阻塞等待功能實現(xiàn)等待一組協(xié)程結(jié)束,保證了其goroutine按照順序執(zhí)行
package main import ( "fmt" "time" ) var ch = make(chan int) func task(i int){ fmt.Println("task...",i) time.Sleep(time.Second) - ch } func main(){ for i:= 0;i10;i++{ go task(i) ch - i } fmt.Println("over") }
運行結(jié)果:
task... 0
task... 1
task... 2
task... 3
task... 4
task... 5
task... 6
task... 7
task... 8
task... 9
over
補充:Go中使用Channel等待所有協(xié)程結(jié)束
讓main方法等待所有協(xié)程執(zhí)行完畢再退出??赡芤话闼悸肥窃O(shè)置一個共有變量,然后通過修改這個變量的狀態(tài)。這是通過共享變量來通信的方式,而go要做的是,通過通信來共享內(nèi)存。
每次通信進行成對通信,當(dāng)main向協(xié)程發(fā)送一個寫channel時,同時也等待協(xié)程返回一個讀channel。
這兩個channel一定是成對的,所以構(gòu)造一個結(jié)構(gòu)體
type worker struct { in chan int done chan bool } func chanDemo1(){ var workers [10]worker for i := 0; i 10; i++ { workers[i] = createWorker1(i) } for i := 0; i 10; i++ { workers[i].in - 'a' + i - workers[i].done } for i := 0; i 10; i++ { workers[i].in - 'A' + i - workers[i].done } } func createWorker1(id int) worker { work := worker{ in: make(chan int), done: make(chan bool), } go func() { for { fmt.Printf("Work %d receiverd %c\n", id, - work.in) work.done - true } }() return work } func main(){ chanDemo1() fmt.Println("over") }
這個執(zhí)行結(jié)果完全是按照0-9,先小寫再大寫的順序
如果這樣順序執(zhí)行,還要協(xié)程干啥
type worker struct { in chan int done chan bool } func chanDemo1(){ var workers [10]worker for i := 0; i 10; i++ { workers[i] = createWorker1(i) } for i := 0; i 10; i++ { workers[i].in - 'a' + i } for _, worker := range workers { - worker.done } for i := 0; i 10; i++ { workers[i].in - 'A' + i } for _, worker := range workers { - worker.done } } func createWorker1(id int) worker { work := worker{ in: make(chan int), done: make(chan bool), } go func() { for { fmt.Printf("Work %d receiverd %c\n", id, - work.in) work.done - true } }() return work }
這樣的話,先打印小寫,再打印大寫,但是大小寫時順序不固定
func chanDemo1(){ var workers [10]worker for i := 0; i 10; i++ { workers[i] = createWorker1(i) } for i := 0; i 10; i++ { workers[i].in - 'a' + i } for i := 0; i 10; i++ { workers[i].in - 'A' + i } for _, worker := range workers { - worker.done - worker.done } } func createWorker1(id int) worker { work := worker{ in: make(chan int), done: make(chan bool), } go func() { for { fmt.Printf("Work %d receiverd %c\n", id, - work.in) // 再開一個協(xié)程 go func() { work.done - true}() } }() return work }
這種方式就是完全隨機了
使用channel進行樹的遍歷
func (node *Node) TraverseFunc(f func(*Node)){ if node == nil{ return } node.Left.TraverseFunc(f) f(node) node.Right.TraverseFunc(f) } func (node *Node) TraverseWithChannel() chan *Node{ out := make(chan *Node) go func() { node.TraverseFunc(func(node *Node) { out - node }) close(out) }() return out } func main(){ var root Node root = Node{Value:3} root.Left = Node{} root.Right = Node{5,nil,nil} root.Right.Left = new(Node) root.Left.Right =Node{6,nil,nil} root.Traverse() c:=root.TraverseWithChannel() maxNode := 0 for node := range c{ if node.Value > maxNode{ maxNode = node.Value } } fmt.Println("max node value:", maxNode)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。
標(biāo)簽:欽州 重慶 汕頭 銅川 雞西 蘭州 吐魯番 梅河口
巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《go等待一組協(xié)程結(jié)束的操作方式》,本文關(guān)鍵詞 等待,一組,協(xié)程,結(jié)束,的,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。