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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
$ cat mutil-goroutines-sync.go
package main
import (
"fmt"
)
// 两个task互相协作,通过两个channel来互相通知对方执行的阻塞和继续
// 因为c2其实是一个带缓冲的(1)的channel,会阻塞主直到另外一个task处理
func task1(c1 chan bool,c2 chan bool) {
for i:= 1;i< 11;i += 2{
// c2是一个带缓冲的channel,因此第一次打印12后到这里会等待读取c2
<- c2
fmt.Printf("%d",i)
fmt.Printf("%d",i+1)
c1 <- true
}
}
func task2(c1 chan bool,c2 chan bool,c3 chan struct{}) {
char_seq := [...]string{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J"}
for i:=0;i<10;i += 2{
<- c1
fmt.Printf("%s", char_seq[i])
fmt.Printf("%s", char_seq[i+1])
c2 <- true
}
// 通知主进程任务执行完成
c3 <- struct{}{}
}
func main() {
c1 := make(chan bool)
// 通过有缓冲的channel来争抢执行
c2 := make(chan bool,1)
// 定义一个struct{}类型的channel
done := make(chan struct{})
// 创建两个goroutine在后台执行
go task1(c1,c2)
go task2(c1,c2,done)
// 继续执行,此时channel c2开始通过值告诉task1开始执行
fmt.Println("begin")
c2 <- true
// 通过一个struct{}类型的channel将主进程阻塞住
<- done
}
$ go run mutil-goroutines-sync.go
begin
12AB34CD56EF78GH910IJ%
|