標籤:++ 雙向 ring cas 而不是 one 讀取 通訊 bre
package main;import ("fmt""runtime""sync")//goruntine奉行通過通訊來共用記憶體,而不是共用記憶體來通訊//channel是goruntine溝通的橋樑,大都是阻塞同步的//通過make建立,close關閉//channel是參考型別//使用for range來迭代操作channel//可設定單向或雙向通道//可設定緩衝大小,在未被填滿前不會發生阻塞func main() {//這裡需要設定chan的類型ch := make(chan bool);go func() {fmt.Println("run...");ch <- true;}();//這裡是阻塞的,等到匿名函數執行完成,給ch設定為true時//這裡能讀取出資料時,就退出。<-ch;ch1 := make(chan bool);go func() {fmt.Println("run...");ch1 <- true;close(ch1);}();//對chan進行迭代操作時,必須在某個地方關閉該chan,不然會發生死結for v := range ch1 {fmt.Println(v);}//有緩衝是非同步ch2 := make(chan bool, 1);go func() {fmt.Println("run...");<-ch2;}();ch2 <- true;//使用多核runtime.GOMAXPROCS(runtime.NumCPU());ch3 := make(chan bool, 10);for i := 0; i < 10; i++ {go run(ch3, i);}//這裡讀取10次,跟上面go run()執行次數相同//保證10次運行都執行完,才退出for i:= 0; i < 10; i++ {<-ch3;}//這裡建立任務wg := sync.WaitGroup{};wg.Add(10);for i := 0; i < 10; i++ {go run2(&wg, i);}//等待所有任務完成wg.Wait();//有多個chan時,如何處理ch4, ch5 := make(chan int), make(chan string);//用於判斷是否關閉ch6 := make(chan bool);go func() {for {select {case v, ok := <-ch4:if !ok {ch6 <- true;break;}fmt.Println(v);case v, ok := <-ch5:if !ok {ch6 <- true;break;}fmt.Println(v);}}}();ch4 <- 1;ch4 <- 2;ch5 <- "hello";ch5 <- "world";close(ch4);close(ch5);//迴圈讀取二次for i := 0; i < 2; i++ {<-ch6;}}func run(ch chan bool, ix int) {a := 0;for i := 1; i < 10000; i++ {a += i;}fmt.Println(ix, a);//給chan傳遞true,說明該run執行結束ch <- true;}func run2(wg *sync.WaitGroup, ix int) {a := 0;for i := 1; i < 10000; i++ {a += i;}fmt.Println(ix, a);//任務完成wg.Done();}
go語言中的並發