channel

一、channel

1. 前言

channel是Golang在语言层面提供的goroutine间的通信方式,比Unix管道更易用也更轻便。channel主要用于进程内各goroutine间通信,如果需要跨进程通信,建议使用分布式系统的方法来解决。

2.分类

2.1 带缓冲

带缓冲的channel,只有等缓冲区满了后才会阻塞;

读取一个关闭的channel,会读取到空值;

写入一个已经关闭的channel,会导致死锁;

2.2 不带缓冲

读取/写入一个为nil的channel,会导致阻塞;

读取一个关闭的channel,会读取到空值;

写入一个已经关闭的channel,会导致死锁;

3. 数据结构

1
2
3
4
5
6
7
8
9
10
11
12
13
type hchan struct {
qcount uint // 当前队列的剩余元素数量
dataqsiz uint // 环形队列长度,即可存放的元素个数
buf unsafe.Pointer // 环形队列指针
elemsize uint16 // 每个元素大小
closed uint32 // 关闭状态标识
elemtype *_type // 元素类型
sendx uint // 队列下标,指示元素写入时存放到队列中的位置
recvx uint // 队列下标,指示元素从队列的该位置读出
recvq waitq // 等待读消息的goroutine队列
sendq waitq // 等待写消息的goroutine队列
lock mutex // 互斥锁,chan不允许并发读写
}

3.1 环形队列

chan内部实现了一个环形队列作为其缓冲区,队列的长度是创建chan时指定的。

3.2 等待队列

3.3 实现原理和特性

3.3.1. 全局锁

3.3.2. 移入、移除元素

二、select

1
2
3
4
5
6
select {
case <-signals1:

case <-signals2:

}

注意如果signals1和signals2的信号过来,case的执行顺序是随机的。


channel
https://www.zengzx.xyz/2019/12/22/01.知识架构/01.Go/01.基础/03.并发编程/
作者
Eden
发布于
2019年12月22日
许可协议