package main
import("fmt""time")functestGoRoutine(routine_num int){for i :=1; i <5; i++{
fmt.Printf("routine_num is %d ; i is %d\n", routine_num, i)
time.Sleep(10* time.Millisecond)}}funcmain(){gotestGoRoutine(1)gotestGoRoutine(2)
time.Sleep(100* time.Millisecond)}// routine_num is 1 ; i is 1//routine_num is 2 ; i is 1//routine_num is 2 ; i is 2//routine_num is 1 ; i is 2//routine_num is 1 ; i is 3//routine_num is 2 ; i is 3//routine_num is 2 ; i is 4//routine_num is 1 ; i is 4
package main
import"fmt"funcaddDataToChan(myChan chanint){for i :=1; i <=5; i++{
myChan <- i
}// 关闭信道close(myChan)}funcmain(){// 定义一个信道
myChan :=make(chanint,5)// 信道中加入值, 然后关闭信道addDataToChan(myChan)// 遍历信道for myChanData :=range myChan {
fmt.Printf("myChan is %d\n", myChanData)}}//myChan is 1//myChan is 2//myChan is 3//myChan is 4//myChan is 5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2.4: 信道做锁
package main
import("fmt""time")funcincrement(ch chanbool, x *int){// 当前协程在信道存上值,其他的协程就一直阻塞中。
ch <-true*x =*x +1<-ch
}funcmain(){// 注意要设置容量为 1 的缓冲信道
pipline :=make(chanbool,1)var x intfor i :=0; i <1000; i++{goincrement(pipline,&x)}
time.Sleep(time.Second)
fmt.Println("x 的值:", x)}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
三: select-case的用法
使用范围: 仅支持通道使用
作用: 在运行 select 时,会遍历所有(如果有机会的话)的 case 表达式,只要有一个信道有接收到数据,那么 select 就结束。
特性: select中的case是随机执行的,而不是顺序执行的。
注意: 尽量都要写default语句, 如果没写, 又没有命中case则会抛出异常。
基本使用案例:
package main
import("fmt""sync")// 定义两个信道,开两个协程, 往信道中追加数据, 测试结果。funcsendDataToChan(inputChan chanint, inputData int, wg *sync.WaitGroup){defer wg.Done()
inputChan <- inputData
}funcmain(){
chan01 :=make(chanint,1)
chan02 :=make(chanint,1)var wg sync.WaitGroup
wg.Add(2)gosendDataToChan(chan01,1,&wg)gosendDataToChan(chan02,2,&wg)
wg.Wait()select{case outData :=<-chan01:
fmt.Printf("outData is %d\n", outData)case outData :=<-chan02:
fmt.Printf("outData is %d\n", outData)default:
fmt.Printf("no data\n")}}//outData is 2//outData is 1