- [X] 完成基础的 eventloop, 支持 linux 平台
- [ ] 实现各种 demo, 聊天, Dns 等
- [ ] 开发 http-server, 实现 c10k 和添加留言版功能
- [ ] 给 http-server 添加 python 扩展, 可以使用 python 实现简单的业务逻辑
当前异步事件最为成熟也是最为流行的实现方式, 叫做 eventloop(事件轮询). 这个名字怎么来的我也没有考究, 字面理解有事件重复排成队列接收调度的意思.
- 何为异步
只要和 io 有关的就可能会阻塞. 如果程序线性处理, 一直在阻塞在 read() 等待数据, 就会阻塞整个程序, 尤其是服务端程序.
异步就是把程序执行流程打乱. 在该程序阻塞在某个 io 事件, 那么就跳过它,等待会它有数据再过来处理, .
异步是单个执行单元的事情, 和多个执行单元无关, 多线程 / 多进程是用来并行处理增加吞吐量, 或做更加精细的调度.
- 历史
对与异步事件的实现, 业界也是经过了长期探索的. 对于 io 阻塞的问题, Unix 哲学认为开一个进程然后用两个进程通信是简单优雅的, Linux 甚至最开始不支持线程, 因为 linus 认为进程就够了. 很多早期的服务器(某 Java), 就是拼命开线程去搞.
在 1998 年出版的经典 <<UNIX 网络编程卷一>> 就讨论过如果 io 阻塞的时候, 如何实现异步, 并给出了几种方法, 开多线程/多进程, 信号, IO 复用, IO 复用赫然在其中, 但也没有指出 io 复用的正确用法, 也没有过多的介绍,所以可以认为那时 io 复用为核心的 eventloop 还不是主流.
后来 2000 年之后, Nginx, Libevent 等项目向世人展示 eventloop 的正确实现, 并解决了 C10k 的问题. 直到现在, eventloop 已经是业界主流了. 很多网络框架, 数据库 socket, 像 golang 的协程, 底层都是 eventloop 在调度.
- Io 复用端口 poll/epoll/kqueue
eventloop 的实现依赖与底层操作系统的实现, 需要操作系统的 io 复用端口, 当然可以通过跨平台手法封装不同操作系统的底层实现.
在 linux 上是 Epoll
基本是 c 语言非常擅长处理的链队列
唤醒队列 : event–>event–>event–>event–>event
fd 数组 : [fd1, fd2, fd3, fd4, fd5, fd6,] read read event write write event timer timer event
fd 数组使用 fd 作为下标, 在 linux 中打开的文件描述符号, 从 0 开始排序, 所以是可以的.
每个 fd 有读, 写, 信号, 定时等事件, 通过链表到某个 fd 中, 把 fd 注册进 epoll, 当 fd 某个事件唤醒时, 根据唤醒事件把 event 插入到唤醒队列中统一处理.