Go channel简介
作者:互联网
channel
用于在并发单元之间通信,类似于管道
ch := make(chan int) // 创建一个channel
defer close(ch)
ch <- v // 向管道中写入
v := <-ch // 从管道读取
v, ok := <-ch
- channel类型
channel有三种类型[可读可写 | 只读 | 只写]
chan T // rw
chan<- T // w
<-chan T // r
- 阻塞和非阻塞
如果在创建一个channel的时候指定了容量,则这个chan就是非阻塞的;否则是阻塞的(并且如果检测到主程序有【读/写】,并发程序里没有【写/读】,或者缓冲区满了,就会报deadlock)
阻塞式或者缓存满状态下的非阻塞式的读写都会被block
ch1 := make(chan int) //阻塞式
ch2 := make(chan int, 10) //非阻塞,缓冲区为10
// deadlock
ch1 <- 1
// deadlock
for i:=0;i<=10;i++{
ch2 <- i
}
// 正常
go func(){
ch1 <- 1
}
i := <-ch1
// 正常
go func(){
i := <-ch1
}
ch1 <- 1
// 正常
ch2 <- 1
v := <-ch2
- 读写操作
在向管道写入之前,会将表达式的值计算出来
如果往已经close的channel中写,会报panic;如果是读,则会立即返回该类型的零值,可以用ok字段来检查
// ch <- 7
ch <- (3+4)
close(ch)
// panic
ch <- 1
// 检查
v, ok := <- ch
- 协程同步
利用chan的阻塞机制,可以用于
- 等待协程执行完成
func sum(s []int, c chan int) {
sum := 0
for _, v := range s{
sum += v
}
c <- sum
}
func main(){
s := []int{1, 2, 3, 4, 5}
c := make(chan int)
go sum(s[:len(s)/2], c)
go sum(s[len(s)/2:], c)
// 用于等待协程执行完成
x, y := <-c, <-c
// 或者这样写
for half := range c{
// half先后得到x和y
// 一直等待到c被关闭
}
}
- 实现协程中的同步操作(这里读写有点类似于进程同步里的PV操作)
比如下面的例子,worker在执行完成之后,通过done通知主协程继续执行
func worker(done chan bool){
time.Sleep(time.Second)
done <- true
}
func main(){
done := make(chan bool, 1)
go worker(done)
<- done
}
- select
比较类似于switch,就是每个case是一个跟管道相关的操作,select会从当前能够执行的case中随机选择一个执行
如果所有case都不能执行,就会执行default
如果default不存在,就会阻塞,或者用time.After自行定义超时操作
select {
case c <- x:
x, y = y, x+y
case <-quit:
fmt.Println("quit")
return
case <-time.After(time.Second * 1):
fmt.Println("timeout")
}
- Timer和Ticker
Timer是一个定时器,可以指定一段之间之后执行,通过chan完成
timer := time.NewTimer(time.Second * 2)
go func(){
<-timer.C
...
}
// 可以用stop停止
stop := timer.Stop()
if stop {
...
}
Ticker是一个定时触发的计时器,可以指定每隔一段时间执行一次,也是通过chan来完成的
ticker := time.NewTicker(time.Millisecond * 500)
go func (){
for t := range ticker.C {
fmt.Println("tick at ", t)
}
}()
// 可以用stop停止
stop := ticker.Stop()
if stop {
...
}
- reference
标签:int,简介,chan,阻塞,go,time,Go,channel 来源: https://blog.csdn.net/weixin_45698935/article/details/123596419