Go Channel
原理
- 本质上,channel是一个包含:发送Go队列,接收Go队列,由循环数组实现的缓存数据队列,锁这几个元素组成的结构体实现;
sendmsg
阶段:- 如果接收Go队列有值,则直接进行值元素的内存拷贝,并唤醒接收队列;
- 如有缓冲队列且未满,则将值复制到循环队列中;
- 如果有缓冲队列且满了或无缓冲队列,将协程放到channel的
sendqueue
中;
recvmsg
阶段:- 如果缓冲,且无数据,则进入
recvqueue
中,协程挂起(gopack
); - 如果缓冲队列中数据,由从队列中将值拷贝给当前接收者;
- 如果
sendqueue
有协程,则说明缓冲队列已满,则从缓冲队列中取值,并将sendqueue
中取一个协程,将其值拷贝到缓冲循环数组中;
- 如果缓冲,且无数据,则进入
- 上述操作是在mutex锁下进行,所以channel是协程安全的;