golang面试中如何回答epoll的相关问题

epoll的网络模型的提问在面试过程中会被经常涉及,下面我来谈一下如果是我应该如何展开这个问题。

一般来说,我的习惯是先从多路复用的概念入手——>再聊Golang中的netpoller——>接着对比一下select/poll——>最后看面试官的兴趣决定是否提触发模式。

1. 多路复用的概念

所谓 I/O 多路复用指的就是 select/poll/epoll 这一系列的多路选择器:支持单一线程同时监听多个文件描述符(I/O 事件),阻塞等待,并在其中某个文件描述符可读写时收到通知。 I/O 复用其实复用的不是 I/O 连接,而是复用线程,让一个 thread of control 能够处理多个连接(I/O 事件)

2. Golang的底层网络模型是基于epoll实现的

Go 是一门跨平台的编程语言,而不同平台针对特定的功能有不同的实现,这当然也包括了 I/O 多路复用技术,比如 Linux 里的 I/O 多路复用有 select、poll 和 epoll,而 freeBSD 或者 MacOS 里则是 kqueue,而 Windows 里则是基于异步 I/O 实现的 iocp,等等;因此,Go 为了实现底层 I/O 多路复用的跨平台,分别基于上述的这些不同平台的系统调用实现了多版本的 netpollers。

Go netpoller 通过在底层对 epoll/kqueue/iocp 的封装,从而实现了使用同步编程模式达到异步执行的效果。总结来说,所有的网络操作都以网络描述符 netFD 为中心实现。netFD 与底层 PollDesc 结构绑定,当在一个 netFD 上读写遇到 EAGAIN 错误时,就将当前 goroutine 存储到这个 netFD 对应的 PollDesc 中,同时调用 gopark 把当前 goroutine 给 park 住,直到这个 netFD 上再次发生读写事件,才将此 goroutine 给 ready 激活重新运行。显然,在底层通知 goroutine 再次发生读写等事件的方式就是 epoll/kqueue/iocp 等事件驱动机制。

Go将多路复用器的操作进行了抽象和适配:

  • 将新建多路复用器抽象为了netpollinit()
  • 将插入监听事件抽象为了netpollopen()
  • 将查询事件抽象为了netpoll()
  • 最终返回等待事件的协程列表

同时Network Poller是Runtime中抽象多路复用器的工具,可以自动检测多个Socket的状态,由垃圾回收器周期地驱动。在查询到Socket状态可用时,快速返回成功;在Socket状态不可用时,休眠等待。(详细的信息存储在PollDesc中)

3. epoll本身的机制及与select/poll的对比

  • epoll 在内核里使用红黑树来跟踪进程所有待检测的文件描述字,把需要监控的 socket 通过 epoll_ctl() 函数加入内核中的红黑树里,红黑树是个高效的数据结构,增删改一般时间复杂度是 O(logn)。而 select/poll 内核里没有类似 epoll 红黑树这种保存所有待检测的 socket 的数据结构,所以 select/poll 每次操作时都传入整个 socket 集合给内核,而 epoll 因为在内核维护了红黑树,可以保存所有待检测的 socket ,所以只需要传入一个待检测的 socket,减少了内核和用户空间大量的数据拷贝和内存分配。
  • epoll 使用事件驱动的机制,内核里维护了一个链表来记录就绪事件,当某个 socket 有事件发生时,通过回调函数内核会将其加入到这个就绪事件列表中,当用户调用 epoll_wait() 函数时,只会返回有事件发生的文件描述符的个数,不需要像 select/poll 那样轮询扫描整个 socket 集合,大大提高了检测的效率。

4. epoll的触发模式 epoll 支持两种事件触发模式,分别是边缘触发和水平触发。

  • 边缘触发 使用边缘触发模式时,当被监控的 Socket 描述符上有可读事件发生时,服务器端只会从 epoll_wait 中苏醒一次,即使进程没有调用 read 函数从内核读取数据,也依然只苏醒一次,因此我们程序要保证一次性将内核缓冲区的数据读取完;
  • 水平触发 使用水平触发模式时,当被监控的 Socket 上有可读事件发生时,服务器端不断地从 epoll_wait 中苏醒,直到内核缓冲区数据被 read 函数读完才结束,目的是告诉我们有数据需要读取;
#我的求职思考##后端##春招#
全部评论
go多路复用是采用的多Reactor/多线程模型吗
2 回复 分享
发布于 2023-02-11 01:20 湖北
m 感谢!
点赞 回复 分享
发布于 2023-03-20 18:57 湖北
感谢,正好我的项目中有涉及epoll多路复用相关,估计会被拷打
点赞 回复 分享
发布于 2023-02-10 14:58 江苏

相关推荐

点赞 评论 收藏
分享
明明就不饿:看不懂你到底会啥,什么岗位
点赞 评论 收藏
分享
评论
14
109
分享

创作者周榜

更多
正在热议
更多
# 春招至今,你的战绩如何? #
8136次浏览 75人参与
# 你的实习产出是真实的还是包装的? #
1493次浏览 37人参与
# 米连集团26产品管培生项目 #
5337次浏览 213人参与
# 军工所铁饭碗 vs 互联网高薪资,你会选谁 #
7266次浏览 40人参与
# 简历第一个项目做什么 #
31433次浏览 319人参与
# 当下环境,你会继续卷互联网,还是看其他行业机会 #
186697次浏览 1118人参与
# 巨人网络春招 #
11265次浏览 223人参与
# 研究所笔面经互助 #
118827次浏览 577人参与
# 重来一次,我还会选择这个专业吗 #
433206次浏览 3924人参与
# 简历中的项目经历要怎么写? #
309816次浏览 4176人参与
# 面试紧张时你会有什么表现? #
30452次浏览 188人参与
# AI时代,哪些岗位最容易被淘汰 #
63109次浏览 773人参与
# 正在春招的你,也参与了去年秋招吗? #
362991次浏览 2635人参与
# 你怎么看待AI面试 #
179654次浏览 1206人参与
# 职能管理面试记录 #
10766次浏览 59人参与
# 网易游戏笔试 #
6420次浏览 83人参与
# 腾讯音乐求职进展汇总 #
160518次浏览 1108人参与
# 校招笔试 #
469104次浏览 2960人参与
# 把自己当AI,现在最消耗你token的问题是什么? #
7136次浏览 157人参与
# 你觉得通信/硬件有必要实习吗? #
155421次浏览 1065人参与
# 小红书求职进展汇总 #
227018次浏览 1358人参与
# 从哪些方向判断这个offer值不值得去? #
56721次浏览 357人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务