libevent的笔记

来源:互联网 发布:淘宝账号怎么快速升心 编辑:程序博客网 时间:2024/04/30 13:54

写在前面

之前阅读libevent的笔记,现放在网上,不是很详细,但可能对某些纠结于某点的人有帮助。

libevent

  • 将fd读写、信号、DNS、定时器抽象为一个个event
  • 多个event由一个event_base结构来管理
  • 整个对于事件的监听以及处理由event_base_loop来驱动
  • libevent也可以理解为对select、poll、epoll的封装
  • 因为整个库对于事件的监听完全来源于select、poll、epoll,所以说libevent实际上是同步的,跟select、poll、epoll一样
  • 一般说epoll是异步的,实际上通过源码,epoll也是同步,也需要轮训,轮训的工作专门交给其他线程来做,工作线程阻塞
  • 相比select,epoll的好处是每次调用时不用重复拷贝监听描述符集,而select每次调用都需要拷贝到内核态,epoll在第一次调用时就会与监听描述符集建立连接
  • libevent时在编译时根据优先级确定eventop,到底使用select、poll还是epoll
  • eventop根据select、poll或者epoll返回的fd来去匹配对应的注册事件,数组下标索引,类似于哈希表,时间复杂度O(1)

libevent的就绪链表

  • 就绪链表的个数根据优先级的个数来的
  • event_base_new默认将优先级个数设为1
  • 当将事件放到就绪链表时,会根据事件的优先级来放入哪个就绪链表
  • 当处理就绪链表的事件时,调度策略是根据优先级来的,源码是利用循环,比如先处理优先级为0的就绪链表,再处理1、2…
    注意:源码中event_base_loop的每个循环只处理某个优先级的就绪链表,剩下的在后续循环中处理

信号是如何抽象为事件的

  • libevent采用了套接字对的形式,一端写,一端读
  • 这样当信号发生时,可以通过一端写,来触发fd可读位掩码返回
  • 那么通过select、poll、epoll监听也能完成对信号的监听,并且统一作为事件处理

定时器是如何实现的

  • 不论是再使用select,poll还是epoll时,都需要设置超时时间
  • 如果将所有定时事件的最小时间作为超时时间,这样在超时时间过去时,select、poll、epoll返回,可以直接将最小时间的定时事件加入到就绪链表
  • 取最小时间用的是最小堆,而且是那种交换优化的最小堆

同步与异步、阻塞与非阻塞

  • 同步与异步是对应的,它们是线程之间的关系,两个线程之间要么是同步的,要么是异步的
  • 阻塞与非阻塞是对同一个线程来说的,在某个时刻,线程要么处于阻塞,要么处于非阻塞
  • 阻塞是使用同步机制的结果,非阻塞则是使用异步机制的结果

C语言内存分配函数

  • alloca 在栈上分配
  • malloc 在堆上分配
  • calloc 分配及初始化
  • realloc 重新分配,相当于vector的扩容