j421037 / epoll-example

To deepen my understanding of epoll.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

学习epoll源码后写此项目加深印象

关于几点学习总结

  1. epoll不需要每次wait都将文件描述符从用户态拷贝到内核态,因为它在调用epoll_ctl时已经将对应的fd拷贝到了内核空间,并不存在网上说的一些什么内核空间和用户空间通过mmap共享一块内存的机制(具体实现可以看内核源码这一行)。通过epoll_create创建的eventpoll对象和通过epoll_ctl创建的epitem对象都是存储在内核的slab中(至于slab是什么并没有深入研究,简单理解就是一块连续的读写效率都很高的内存)。
  2. epoll_ctl会在对应fd的等待队列entry上注入ep_poll_callback函数,实现当fd就绪后唤醒epoll进程等待队列上的进程。
  3. epoll只会将就绪的文件描述符对应的epoll_event从内核空间拷贝到用户空间(具体可以看这一行),相比于select每次都拷贝全部fd效率无疑大大提升。
  4. ET模式和LT模式区别仅在于源码这一段,如果是边缘触发,那么就不加回可用列表,因此只能等到下一个可用事件触发的时候才会将对应的epi放到可用列表里面。简单来说,如果我写了一段socket程序,设置成LT模式,那么在收到监听socket可读事件时,可以仅accept一次,然后调用epoll_wait处理下一个链接;但是设置成ET模式就必须循环accept,因为在大并发的情况下,同时向服务器发起多个链接是很正常的,而监听socket只会触发一次可读事件,如果只接受一个链接那么会后面的链接就无法建立。

example写了点啥

就是一个最简易的server,只处理了socket连接,随即就关闭了。

How to run

  1. make server
  2. ./server --mode 0|1 [--et] [--loop-accept] --port 1234 [--sleep n(s)]

详解请见博客

About

To deepen my understanding of epoll.


Languages

Language:C 97.6%Language:Makefile 2.4%