/eventloop

用 C 语言实现异步事件机制,在此基础上实现 http server。learn more from libevent.

Primary LanguageC

开发进度

  • [X] 完成基础的 eventloop, 支持 linux 平台
  • [ ] 实现各种 demo, 聊天, Dns 等
  • [ ] 开发 http-server, 实现 c10k 和添加留言版功能
  • [ ] 给 http-server 添加 python 扩展, 可以使用 python 实现简单的业务逻辑

eventloop 简介

当前异步事件最为成熟也是最为流行的实现方式, 叫做 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 插入到唤醒队列中统一处理.