走读 Linux(5.0.1)源码,理解 TCP 网络数据接收和读取工作流程(NAPI)。
要搞清楚数据的接收和读取流程,需要梳理这几个角色之间的关系:网卡(本文:e1000),主存,CPU,网卡驱动,内核,应用程序。
本章整理了一下服务端 tcp 的第三次握手和 epoll 内核的等待唤醒工作流程。
做服务端多年,但是学习 linux 内核才一年多,深入研究源码后,解决了我之前的很多疑惑。
前段时间在回答知乎问题时,顺便做了个小结,现在把自己的回答整理了一下搬到这里。
学习流程:熟练使用应用层接口 -> 理解工作原理 -> 搭建内核调试环境 -> 画图串联知识点 -> 解决问题。
如题,主要搭建 linux 内核的调试环境。
qemu 模拟器运行 linux,然后通过 gdb 调试 linux 内核源码。
前段时间曾出过两个视频,比较粗糙,最近重新整理了一下环境搭建流程,还加入了网桥搭建流程,可以调试 linux 内核虚拟网卡的驱动部分源码。
知乎问题:
1.网上针对epoll_wait的惊群讨论几乎都是围绕listen socket的accpet来做讨论的,socket是否只有此种情况会导致惊群? 将accpet返回的socket加入到epoll中,这个socket的可读,可写事件是否也会导致惊群?
2.如果1中描述的accept返回的socket的可读,可写事件不会导致惊群。那么是否可以采用 ①一个listen socket加入到一个epoll(1)中,并且自始至终只用一个线程(1)来调用epollwait和accpet;② accpet返回的所有套接字都加入到另外一个epoll(2)中,然后线程2-N同时针对第2个epoll调用epoll_wait 的方式来应对连接数多但不是同时connect的开发场景?
知乎问题:
Web服务器nginx使用ET模式的epoll。我想问,它相对LT模式epoll有哪些优势呢?另外一篇帖子(epoll的边沿触发模式(ET)真的比水平触发模式(LT)快吗?(当然LT模式也使用非阻塞IO,重点是要求ET模式下的代码不能造成饥饿))说ET不一定比LT快,那么为什么要使用ET模式呢?
知乎问题:
看网上的说法,在LT模式+EPOLLEXCLUSIVE的情况下,当有新事件发生的时候,线程被唤醒,之后会调用ep_scan_ready_list,主要做两个事情:
调用传入的回调参数ep_send_events_proc把确实可读/写的事件从ready list挪到用户空间,如果是LT模式,那么会把事件留在ready list中 如果发现ready list没有为空的话,那么wake_up一下epoll中的等待队列,在EPOLLEXCLUSIVE情况下是唤醒一个,否则全部唤醒 如果我上面说的大概没错。。。我的问题是,假设LT+EPOLLEXCLUSIVE前提下,3个线程都在epoll_wait等一个fd,现在fd出现可写事件,线程A被唤醒,线程A从epoll_wait返回的路上会按照上文所说的情况,再次唤醒一个线程。这样线程B也被唤醒,同理线程B从epoll_wait返回的路上还会唤醒线程C。
这样的话,岂不还是惊群?小白求解答
知乎问题:
协程的一个典型应用是:单线程上开启多协程去执行某个既包含cpu运算、又包含io操作的函数。在开始执行io操作之后切换到另一个函数上执行cpu运算,在上一个函数的io操作结束后再切换回来。
不太懂程序语言如何设计可以达到这一点?
能否以c/c++/java/python举例来说明?
知乎问题:
程序员编码过程中总会碰到很多 bug,这些 bug 都应该算是我们的一种阅历,非常想把这些犯过的错误记录下来,所以说大家都是用什么来做 bug 笔记的呢?
现在个人在用 Evernote 做一些记录,但是碰到了一下问题:
知乎问题:
这是Quora上的一个问题,看了以后觉得有点意思,想看看国内的程序员是什么情况呢?Question on @Quora: How does your desk look as a programmer?
知乎问题:
内存池的优点就是可以减少内存碎片,分配内存更快,可以避免内存泄露等优点。那我们如何去设计一个内存池呢?能不能给个你的大致思考过程或者步骤,比如,首先要设计一个内存分配节点(最小单元),再设计几个内存分配器(函数),等等。不是太清晰。望大神指点。
知乎问题:
POLLIN,POLLOUT,POLLERR这三个是比较显而易见的,其余的诸如POLLHUP,POLLNVAL,POLLPRI这些就比较让人摸不着头脑了,这些poll/epoll中的event应该在什么时候需要监听并处理他们呢?
perf 是常用的性能分析工具,记录基本使用方法。
glibc 这个 c 库,封装了很多代码,可以通过 gdb 调试进去深入理解底层源码。