为了账号安全,请及时绑定邮箱和手机立即绑定

【九月打卡】第21天 go的-go的网络层实现

标签:
Go

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

  

课程章节:8-1,8-2


课程讲师:Moody


课程内容:

※ go的网络层实现

  • 在底层使用操作系统的多路复用IO,比如linux的epoll

  • 在协程层次使用阻塞模型

  • 当协程被阻塞的时候,协程直接休眠,等待被唤醒

※ go里面调用epoll的方法

  • epoll_create() -> netpollinit()

  • epoll_ctl() -> netpollopen()

  • epoll_wait() -> netpoll()

※ netpillinit

  1. 调用系统方法(以linux为例),汇编直接调用epoll_create 创建一个epoll

  2. 新建一个系统的pipe管道用于通知中端Epoll

  3. 将"管道有数据到达"事件注册到Epoll里面

※netpollopen

  1. 传入一个socket的FD和pollDesc指针

  2. pollDesc是go对一个socket的相关信息的抽象

  3. pollDesc还记录了等待socket读写事件的协程

  4. 将Socket可读,可写,断开事件注册到Epoll里面

※netpoll

  1. 调用epoll_wait() 查询那些事件发生了

  2. 根据Socket相关的pollDesc信息,返回那些协程可以唤醒,因为这些协程是关心event的


https://img1.sycdn.imooc.com//632ecf3c0001a17525341531.jpg


※补充:

go的用户层看来,协程虽然是阻塞I/O模型,Socket是阻塞的,因为抽象了Socket的pollDesc是阻塞的。但是实际上,这是go的netpoller通过I/O多路复用机制模拟出来的,对应的底层操作系统Socket实际上是非阻塞的,只是在运行时,拦截了针对底层Socket的系统调用返回的错误码,并通过netpoll而和 协程调度让协程阻塞在用户层所看到的Socket描述符上。                                                                                        比如:当用户层针对某一个socket描述符发起read操作的时候,如果该socket上尚无可读数据,那么go运行时会将该socket加入到netpoller中监听,直到go收到该socket数据可读的通知,也就是事件。接着,go才会唤醒关心这个sokcet 的read事件的协程。这个过程,从协程的视角来看,就像read事件一直阻塞在Socket描述符上面一样



点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
PHP开发工程师
手记
粉丝
2
获赞与收藏
4

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消