内核和用户进程协作之epoll

epoll

进程的上下文切换在linux环境下是一笔不小的开销,为了更高效地对海量用户提供服务,必须让一个进程可以同时处理很多TCP连接才行。

其实这个事情linux系统已经替我们做好了,它就是我们所熟知的IO多路复用,这里的复用指的是对进程的复用

在linux上多路复用的方案有 select、poll、epoll。而epoll性能最为突出。和其相关的三个函数是:

  • epoll_create: 创建一个epoll对象
  • epoll_ctl: 想epoll对象添加要管理的连接
  • epoll_wait: 等待其管理的连接上的IO事件

总结

1 阻塞到底是怎么一回事?

阻塞其实说的是进程因为等待某个事件而主动让CPU挂起的操作。所以分析某个技术方案是不是阻塞的时候,关键要看进程有没有放弃CPU,如果放弃了,那就是阻塞。 如果没有,那就是非阻塞。

2 同步网络IO都有哪些开销?

同步阻塞IO有多次进程上下文开销,从开发者角度来看,进程上下文切换其实没有再做有意的工作,如果是网络密集IO应用,CPU就不停的进程切换,CPU吭哧吭哧累的要死,还被程序员吐槽性能差。

一句话总结那就是: 同步阻塞网络IO是高性能网络开发路上的绊脚石!,所以服务端的网络IO模型里,没有人使用同步阻塞网络IO.

3 多路复用epoll为什么就能提高网络性能?

其实epoll高性能的最根本原因是极大地减少了无用的进程上下文切换,让进程更专注地处理网络请求。

在内核态的硬、软中断上下文中,包从网卡接受过来进行处理,然后放到socket的连接队列,再找到epitem,并将它添加到epoll对象的就绪链表中。

在用户进程中,通过调用epoll_wait来查看就绪链表是否有事件到达,如果有,直接拉取走进行处理,处理完毕再次调用epoll_wait,在高并发实践中,只要活足够多,epoll_wait根本不会让进程阻塞。用户进程会一直干活,直到epoll_wait无活可干,才主动让出CPU。 这就是epoll高效的核心原因所在!

至于红黑树,仅仅是提高了epoll查找、添加、删除的效率而已,不算epoll在高并发场景高性能的根本原因。

4 epoll也是阻塞的?

阻塞说的是进程因为等待某个事件而主动让出CPU挂起的操作。 阻塞不会导致低性能,过多地频繁的阻塞才会。 epoll的阻塞和它的高并发并不冲突。

5 为什么redis的网络性能会突出?

Redis的主要业务逻辑都是在本机内存上的数据结构的读写,几乎没有网络IO和磁盘IO,单个请求处理的很快,所以干脆就做成了单进程的,这样就避免了多进程的协作的负担,减少了进程切换。

其进程主要的工作就是调用epoll_wait等待事件,处理完成之后在调用,一直工作到无事可做,让出CPU。

最后

在行里和工作中,你一定也见过这样的大神程序员,一个人就能写出非常优秀的项目。 对于大神来说,省去了和他人交流和沟通的成本,反而工作效率能发挥到极致。这感觉和redis有点像。

版权声明:
作者:jeristiano
链接:https://www.jeristiano.win/archives/641.html
来源:光合盐
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>
文章目录
关闭
目 录