golang的協程和通道的分析
阿新 • • 發佈:2019-01-29
每個協程對應於每個併發的事件,程式可以不用協程,這樣執行的效率不如用協程的要快。
同時執行的協程數,與cpu數進行匹配最合適,否則會出現deadlock。
協程間的通訊,通過chan來實現,而多個chan可以組成管道,來順序的傳遞資料。
<-在chan的左側是用於輸出,<-在chan的右側是用於輸入,在函式呼叫時可以通過<-來設定chan的讀寫許可權。
寫個demo如下:
在main函式中,首先對同時執行的協程數量進行限定。package main import ( "fmt" "runtime" ) const ( cnt =2 //併發處理的數量 ) var vcnt int func begin(id string, in chan<- string) { in<- fmt.Sprintf("set in chan %s",id) fmt.Println("in begin, in chan ",id) vcnt++ if vcnt >= cnt { close(in) } } func media(in <-chan string,out chan<- string) { for d:=range in { fmt.Println("in media "+d) out<-d } close(out) } func end(out <-chan string,done chan<- int) { for d:= range out { fmt.Println("in end "+d) } done<-1 close(done) } func main() { maxProcs := runtime.NumCPU() //獲取cpu個數 runtime.GOMAXPROCS(maxProcs) //限制同時執行的goroutines數量 vcnt=0 in := make(chan string,cnt) out :=make(chan string) done :=make(chan int) for i:=0;i<cnt;i++ { go begin(string(i+'0'),in) } go media(in,out) go end(out,done) <-done }
三個chan中,in是輸入chan,通過cnt個協程分別進行寫入,對in設定cnt個緩衝區,保證能併發的寫入
out是輸出chan,在media中把in傳遞到out,在end中完成輸出
done是標識chan,用來通知主函式,end協程執行完畢,可以退出了。用sync.WaitGroup是更加通用的做法。
另外,對於chan的close,是告知讀入chan已完成,無新的資料讀入了。