channel
使用通信来共享内存,而不是使用共享内存在通信
基础
channel 只能使用 make 生成
make(chan type, n int)
创建一个缓冲区大小为n的channel,超过n才会阻塞1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20var c chan int //c == nil
var c chan int = make(chan int)
c := make(chan int)
func channel() {
c := make(chan int)
go func() {
for {
n := <-c
fmt.Println(n)
}
}()
c <- 1
c <- 2
}
/*
1
2
*/不指明方向默认是双向的,可以指定方向
1
2chan<- int //只能发送
<-chan int //只能接收channel 是可以close的
永远是发送方close1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16func channel() {
c := make(chan int)
go func() {
for {
if n, ok := <-c; ok {
fmt.Println(n)
} else {
break
}
}
}()
c <- 1
c <- 2
close(c)
}除了用ok判断是否关闭还可以
1
2
3
4
5
6
7
8
9
10
11func channel() {
c := make(chan int)
go func() {
for n := range c {
fmt.Println(n)
}
}()
c <- 1
c <- 2
close(c)
}select
每个case都必须是一个通信
所有channel表达式都会被求值
所有被发送的表达式都会被求值
如果任意某个通信可以进行,它就执行;其他被忽略。
如果有多个case都可以运行,Select会随机公平地选出一个执行。其他不会执行。
否则:
如果有default子句,则执行该语句。
如果没有default字句,select将阻塞,直到某个通信可以运行;Go不会重新对channel或值进行求值。基础
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
46func main() {
c1 := make(chan int)
c2 := make(chan int)
go func() {
for {
c1 <- 1
c2 <- 2
time.Sleep(time.Duration(rand.Intn(1500)) * time.Millisecond)
}
}()
tick := time.Tick(time.Second)
end := time.After(3 * time.Second)
for {
select {
case n := <-c1:
fmt.Println("c1:", n)
case n := <-c2:
fmt.Println("c2:", n)
case t := <-tick:
fmt.Println("tick: ", t)
case <-end:
fmt.Println("bye")
return
}
}
}
/*
c1 -> 1
c2 -> 2
c1 -> 1
c2 -> 2
c1 -> 1
c2 -> 2
tick
c1 -> 1
c2 -> 2
c1 -> 1
c2 -> 2
tick
c1 -> 1
c2 -> 2
c1 -> 1
c2 -> 2
tick
bye
*/time 库
1
2time.After(d Duration) <-chan Time //d时间后发送一个channel
time.Tick(d Duration) <-chan Time //每d时间发送一个channel传统同步机制
使用共享内存来通信
WaitGroup
Mutex
Cond
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
30type atomicInt struct {
value int
mutex sync.Mutex
}
func (i *atomicInt) increment() {
i.mutex.Lock()
defer i.mutex.Unlock()
i.value++
}
func (i *atomicInt) get() int {
i.mutex.Lock()
defer i.mutex.Unlock()
return i.value
}
func main() {
i := atomicInt{}
fmt.Println(i.get())
go func() {
for ii := 0; ii < 10; ii++ {
i.increment()
}
}()
for ii := 0; ii < 10; ii++ {
i.increment()
}
time.Sleep(time.Second)
fmt.Println(i.get())
}
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 SHIELD!
评论