知乎问题:
协程的一个典型应用是:单线程上开启多协程去执行某个既包含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 调试进去深入理解底层源码。
为了使用 linux 高版本内核功能,使用了 ubuntu 20.4,记录一下使用新系统时的相关软件安装配置。
文件描述符透传,它始终由一个进程(主进程)独占 listen socket,由它去获取资源,然后分派给其它的子进程。
SO_REUSEPORT (reuseport) 是网络的一个选项设置,它能开启内核功能:网络链接分配 内核负载均衡
。
该功能允许多个进程/线程 bind/listen 相同的 IP/PORT,提升了新链接的分配性能。
nginx 开启 reuseport 功能后,性能有立竿见影的提升,我们结合 tcp 协议分析 nginx 的 reuseport 功能。
reuseport 也是内核解决 惊群问题
的优秀方案。
每个进程可以 bind/listen 相同的 IP/PORT,相当于每个进程拥有独立的 listen socket 的完全队列,避免了共享 listen socket 的资源争抢,提升了并发的吞吐。
内核通过哈希算法,将新链接相对均衡地分配到各个开启了 reuseport 属性的进程,所以资源的负载均衡得到解决。
EPOLLEXCLUSIVE
是 2016 年 4.5+ 内核新添加的一个 epoll 的标识(代码改动较小,详看:github)。
它降低了多个进程/线程通过 epoll_ctl 添加共享 fd 引发的惊群概率,使得一个事件发生时,只唤醒一个正在 epoll_wait 阻塞等待唤醒的进程/线程(而不是全部唤醒)。
而 Ngnix 在 1.11.3 之后相应添加了 NGX_EXCLUSIVE_EVENT
功能标识(代码改动较小,详看:github),它使用了 EPOLLEXCLUSIVE 特性。
对比 nginx 在应用层的解决方案:accept_mutex,NGX_EXCLUSIVE_EVENT 它从内核层面避免惊群问题,它更简洁高效。
该功能的工作原和使用相对简单:进程使用 epoll_ctl 添加 listen socket fd 时,把 EPOLLEXCLUSIVE 属性添加进去就可以了。多个进程通过 epoll_wait 等待 listen socket 事件,当有新链接到来时,内核只唤醒一个等待的进程。
我们从应用层(nginx)和内核去分析 epoll 的 EPOLLEXCLUSIVE 属性工作原理。
由主进程创建的 listen socket,要被 fork 出来的子进程共享,但是为了避免多个子进程同时争抢共享资源,nginx 采用一种策略:使得多个子进程,同一时段,只有一个子进程能获取资源,就不存在共享资源的争抢问题。
成功获取锁的,能获取一定数量的资源,而其它没有成功获取锁的子进程,不能获取资源,只能等待成功获取锁的进程释放锁后,nginx 多进程再重新进入锁竞争环节。
本文将通过测试,重现 nginx(1.20.1) 的惊群现象,并深入 Linux (5.0.1) 内核源码,剖析惊群原因。
早期的 accept 同步阻塞睡眠等待资源,当资源到来时,在多个进程或线程上睡眠的 accept 会同时被唤醒处理。后来 Linux 内核增加了 WQ_FLAG_EXCLUSIVE
排它唤醒属性,避免了惊群问题。
本文将深入 Linux 内核(5.0.1)源码,剖析在 TCP 多进程框架下,同步阻塞 accept 的惊群处理。
既然是 TCP 协议的 accept,那不得不了解三次握手和进程睡眠唤醒的原理。