go学习笔记5-channel

  golang中channel是一个比较重要的类型,声明关键字chan

1
2
3
4
5
6
7
8
package main
import "fmt"
func main(){
t := make(chan int, 100)
t <- 5
s := <- t
fmt.Println(s)
}

channel 可以看作是一个管道,<-是它的操作符,当<-在channel右边时表示往channel里面写数据,<-在左边表示从channel读取数据,声明channel时需要制定数据类型,并可以指定缓冲大小,适当的设置缓冲区大小可以提高程序的效率,因为channel在读写数据时,如果channel里面为空或者存满了,读写操作会一直阻塞。这点类似python的队列queue
  前面提到channel会存在阻塞问题,所以当使用多个channel时,可以用select 来监听

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
package main

import "fmt"

func main(){
t := make(chan int, 100)
t2 := make(chan int, 100)
t2 <- 6
t <- 5

select {
case c := <- t:
fmt.Println(c)
case c2 := <- t2:
fmt.Println(c2)
default:
fmt.Println("null")
}
select {
case c := <- t:
fmt.Println(c)
case c2 := <- t2:
fmt.Println(c2)
default:
fmt.Println("null")
}
select {
case c := <- t:
fmt.Println(c)
case c2 := <- t2:
fmt.Println(c2)
default:
fmt.Println("null")
}
}

输出为:
5
6
null
select可以看作channel的switch,它会按代码顺序区判断是否有channel可以读,如果没有channel可读则走default的运算

  select可以结合time设置阻塞超时

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
package main

import (
"fmt"
"time"
)

func main(){
t := make(chan int, 100)
t2 := make(chan int, 100)
t2 <- 6
t <- 5

select {
case c := <- t:
fmt.Println(c)
case c2 := <- t2:
fmt.Println(c2)
default:
fmt.Println("null")
}
select {
case c := <- t:
fmt.Println(c)
case b := <- time.After(time.Second *1):
fmt.Println("time out")
fmt.Println(b)
}
}

输出:
5
time out
2019-01-04 11:24:51.127522602 +0800 CST m=+1.002540136
select 语句在没有设置default的时候,会一直阻塞到其中一个case收到消息位置,time.After()是一个单向的channel,会在延迟指定时间后发送当前时间给返回对象

-------------本文结束感谢您的阅读-------------

本文标题:go学习笔记5-channel

文章作者:fengxi

发布时间:2019年01月04日 - 10:01

最后更新:2019年04月04日 - 21:04

原始链接:https://super-storm.github.io/2019/01/04/go学习笔记5-channel/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。