golang的channel浅析

简介

channel是golang的一个重要特性,可用于goroutine同步和通信,channel基于共享内存实现,具有FIFO特性。

chan的分类

//read and write
chan
//write only
chan<-
//read only
<-chan

此外还可以分为有缓冲无缓冲chan。

无缓冲chan

无缓冲chan,没有缓冲队列,其读写两端需要同步,否之阻塞。可用于goroutine之间的同步操作。

创建无缓冲chan:

ch := make(chan int)
//or: ch := make(chan int, 0)
var rch <-chan int = ch
var wch chan<- int = ch

带缓冲chan

带缓冲的chan有缓冲队列,chan的生产者和消费者可以异步读写,不过再chan缓冲满时写阻塞,在chan的缓冲为空时读阻塞。

创建带缓冲chan:

ch := make(chan int, 20)
var rch <-chan int = ch
var wch chan<- int = ch

其他

迭代chan

可以使用for-range来迭代chan,chan关闭自动退出循环。

for value := range ch {
	//todo...
}

panic

在chan关闭后的读写会产生panic。

屏蔽panic:

val, ok := <-ch
//ok's type is bool

使用ok状态来检查chan是否关闭。

非阻塞

对于无缓冲的chan,只有阻塞读写。

对于有缓冲的chan,可以进行非阻塞读写操作。

首先在缓冲区未满的写,缓冲区未空的读都是非阻塞的。

在缓冲未空的读和缓冲满的写的非阻塞操作

  1. 使用time.timer来进行定时操作,超时退出。(伪的)

  2. 使用len和cap对chan进行测试,然后读写。

    https://golang.google.cn/pkg/builtin/#len

关于chan的线程安全问题

这里将线程安全定义为多个goroutine同时读写一个chan。

chan的读写是线程安全的。

实现原理

【有待填坑】

https://zhuanlan.zhihu.com/p/62391727
https://my.oschina.net/renhc/blog/2246871

你可能感兴趣的:(golang,channel)