手记

【九月打卡】第19天 go--channel学习(2)

课程名称:深入Go底层原理,重写Redis中间件实战


课程章节:7-3,7-4,7-5


课程讲师:Moody


课程内容:

channel发送的情形

◆直接发送

  • 从队列里取出一个等待接收的G,无需先进入缓存

  • 将数据copy到接收的协程变量中

  • 唤醒G 开始工作

◆放入缓存

  • 获取可存入的缓存地址

  • 存入数据

  • 维护索引

◆休眠等待

  • 把自己包装成sudog

  • 将包装好的sudog放入sendq队列里去

  • 休眠协程并解锁

  • 被唤醒后,数据已经被取走了,无需加入缓存,只需要维护下其他的数据

channel接收的情形

◆有等待的协程G,从协程G接收

  • 判断有协程在sendq队列里等待,调用recv()

  • 判断此Channel里没有缓存

  • 直接从等待的协程G里取走数据,唤醒协程G

◆有等待的协程G,从缓存接收

  • 判断有G再发送队列等待,进入recv()

  • 判断此channel有缓存

  • 从缓存里取出一个G copy数据给接受者

  • 把sendq里面的协程取出一个到缓存

◆接收缓存

  • 判断sendq里面有没有等待的协程

  • 判断缓存

  • 从缓存里直接取走数据

◆阻塞接收--无缓冲区

  • 判断recvdq里面有没有等待接收的协程

  • 判断缓冲区是否存在

  • 包装成sodog,放入sendq队列,休眠


※ 非阻塞的channel



0人推荐
随时随地看视频
慕课网APP