在Linux网络编程中,常常使用select和poll来做事件触发,监听socket的读写状态,然后进行读写操作。现在新的linux内核中,增加了epoll事件触发机制,具有更高的性能和更好的设计理念,可以用它来完全代替select和poll。相比于select,epoll最大的好处在于它不会随监听fd数目的增长而降低效率。因为在内核总的select实现中,它是采用轮询来处理的,轮询的fd数目越多,自然耗时越多。并且,在linux/posix_types.h头文件中有这样的声明:
#define __FD_SETSIZE 1024
表示select最多同时监听1024个fd,当然,可以通过修改头文件再重新编译内核来扩大这个数目,但这似乎并不治本。(引自《使用EPOLL进行网络编程》,这篇文章主要是进行一个读写事件的总结,不会过多地讨论epoll,而且本人也是初学)
一、select/poll中的读写事件
1.下列四个条件中的任何一个满足时,套接口准备好多:
a. 有数据可读,专业的说法是:套接字接收缓冲区中的数据字节数大于等于套接字接收缓冲区低潮限度的当前值。可以使用套接字选项SO_RCVLOWAT来设置低潮限度,对于TCP和UDP套接字,其值缺省为1
b. 连接的度这一半关闭,也就是说接收了FIN的TCP连接。对这样的套接字的套接字将不阻塞且返回0(即文件结束符)
c.套接字是一个监听套接字且已完成的连接数为非0,即连接建立后可读
d. 有一个套接字错误待处理。对这样的套接字的读操作将不阻塞且返回一个错误(-1),errno则设置成明确的错误条件。这些待处理的错误也可以通过指定套接口选项SO_ERROR调用getsockopt来取得并清除。
2.下列三个条件中的任一个满足时,套接字准备好写:
a. 缓冲区可写,专业的说法是:套接字发送缓冲区中的可用字节数大于等于套接字发送缓冲区低潮限度的当前值,且或者套接字已连接或者套接字不要求连接(例如UDP套接字),对于TCP和UDP套接字,其缺省值一半为2048
b. 连接的写这一半关闭。对这样的套接字的写操作将产生信号SIGPIPE
c.有一个套接字错误待处理。
二、 epoll的读写事件
EPOLL ET模式下:
读事件的发生条件
1、正常数据到达
2、关闭数据(FIN)到达,即关闭连接
3、连接错误数据(reset)到达
4、连接到到达时(对于监听套接字)
写事件的发生
1、连接建立成功后可写(accept获取的套接字或者客户端建立连接的套接字)
2、缓冲区可写
通过上面的分别阐述,epoll的读写事件区分要比select/poll清晰一些,epoll还有很多优点和细节,在以后的文章中再介绍