对于5K网络服务器IO 模型中,事件驱动模型比较有代表性的有 select , epoll 等,框架有 libevent, libev,  asio, ACE 等框架,比较稳定简单的数 libev 和 asio(boost)。 他们的编程模型大同小异,

今天就拿libev 事件驱动库的服务器模型举例。本文所涉及到的接口Linux接口,不涉及IOCP

简单的一问一答得服务器/客户机模型

多线程服务器:

如果要同时为多个客户机提供服务,则不推荐多进程,如果单个服务执行体需要消耗较多的CPU资源,比如需要进行大规模或长时间的数据运算或文件访问,则进程为安全,否则,推荐线程。

很多程序员考虑用“线程池”或“连接池”,连接池是尽量重用已有的连接,减少创建和关闭连接的频率。如:tomcat和各种数据库等。

但是“池”必须考虑外界响应的规模,调整“池”的大小。

总之,多线程可以提高小规模服务请求响应,但是面对大规模的服务请求,多线程并不是最佳的方案。

事件驱动模型:(Linux 接口)

select:API

FD_ZERO(int fd, fd_set *fds)

FD_SET(int fd, fd_set *fds)

FD_ISSET(int fd, fd_set *fds)

FD_CLR(int fd,  fd_set *fds)
int  select (int nfds,  fd_set *readfds,  fd_set * writefds, fd_set *exceptfds , struct timeval *timeout);

相比而言,select的事件驱动模型只用单线程(进程)执行,占用资源少,但是,select 在探测事件时,采用轮训各个句柄。很多OS提供了更高效的接口,epoll, kqueue 等。select 将事件探测和事件响应夹杂在一起,一旦事件响应的执行体复杂,则会导致事件响应延迟,降低了事件探测的及时性。


事件驱动框架 libevent , libev 等库

这些库,会根据OS的特点选择最合适的事件探测接口,并加入对信号的异步响应。下面介绍用libev替换

select 和 epoll接口,实现高效稳定的服务器模型。