1.底层实现
2.有无缓存区别
3.线程安全
4.使用注意
5.CSP并发模型
6.使用场景
1.底层实现
channel底层是通过循环数组实现的先入先出队列,使用互斥锁保证channel写入和读取数据的线程安全
2.有无缓存区别
(1)创建方式不同, 有缓冲的chan会带上缓冲区大小,make(chan type, size)
(2)阻塞:
无缓冲的读写都会阻塞,有其他协程准备读了, channel才能写入
有缓冲的chan当缓冲满了 写入阻塞
3.线程安全
底层使用互斥锁,保证读写channel队列的线程安全
4.使用注意
(1)已经close的chan
写:panic
读:如果缓冲区还有数据可以读;如果缓冲没有数据,返回空值
close: panic (一个channel不能多次关闭)
(2)未初始化的chan
读写 死锁
关闭 panic
(3)信号通知
如果多个goroutinue都监听同一个channel,那么channel的数据被随机一个gorountine读取消费
如果多个goroutinue都监听同一个channel,这个channel被关闭,所有gorountine都能收到退出信号
5.CSP并发模型
golang基于goroutinue和channel实现csp并发模型,将生产者和消费者解耦
不要通过共享内存来通信,而是使用通信来共享内存
6.使用场景
不同协程之前通信
停止信号监听
定时任务
生产者消费者解耦
控制并发数
runtime/chan.go
type hchan
struct {
// 循环数组中元素的数量
qcount uint // total data in the queue
// 循环数组长度
dataqsiz uint // size of the circular queue
// 循环数组
buf unsafe.Pointer // points to an array of dataqsiz elements
elemsize uint16
// chan是否关闭
closed uint32
elemtype *_type // element type
// 下一次写下标位置
sendx uint // send index
// 下一次读下标位置
recvx uint // receive index