使用linux epoll模型,水平触发模式(Level-Triggered),当socket可写时,会不停的触发socket可写的事件,如何处理?

##第一种方法

  1. 当需要向socket写数据时,将该socket加入到epoll模型(epoll_ctl);等待可写事件。

  2. 接收到socket可写事件后,调用write()或send()发送数据。

  3. 当数据全部写完后, 将socket描述符移出epoll模型。

这种方式的缺点是: 即使发送很少的数据,也要将socket加入、移出epoll模型,有一定的操作代价。

##第二种方法

  1. 向socket写数据时,不将socket加入到epoll模型;而是直接调用send()发送;

  2. 只有当或send()返回错误码EAGAIN(系统缓存满),才将socket加入到epoll模型,等待可写事件后,再发送数据。

  3. 全部数据发送完毕,再移出epoll模型。

这种方案的优点:当用户数据比较少时,不需要epool的事件处理。

在高压力的情况下,性能怎么样呢?

对一次性直接写成功、失败的次数进行统计。如果成功次数远大于失败的次数, 说明性能良好。(如果失败次数远大于成功的次数,则关闭这种直接写的操作,改用第一种方案。同时在日志里记录警告)

##第三种方法

使用Edge-Triggered(边沿触发),这样socket有可写事件,只会触发一次。

可以在应用层做好标记。以避免频繁的调用 epoll_ctl( EPOLL_CTL_ADD, EPOLL_CTL_MOD)。 这种方式是epoll 的 man 手册里推荐的方式, 性能最高。但如果处理不当容易出错,事件驱动停止。