对于I/O操作,有以下几种模型:
1、阻塞I/O(Blocking I/O):udp协议中的recvfrom在接受数据时进行等待就是使用此模型。
不过这样的程序会存在Dos攻击,链接阻塞在read,防止dos攻击的方法是使用非阻塞io,或者使用另外的进程和线程处理逻辑,设置超时等。
接下来我们看看poll,定义如下:
#include <poll.h>
int poll (struct pollfd *fdarray, unsigned long nfds, int timeout);
poll函数的第一个参数是指向名为pollfd的结构体指针。pollfd结构体定义如下:
struct pollfd {
int fd; /* descriptor to check */
short events; /* events of interest on fd */
short revents; /* events that occurred on fd */
};
pollfd里面,events表示等待的事件,revents表示实际发生的事件。根据结果可以做不同的处理。下表是poll的事件定义:
poll的第二个参数表示fdarray的个数,第三个参数是超时时间,单位是毫秒。
poll的例子与select基本类似,这里就不多说,具体参见unp。
最后说poll比select优秀的地方:
(1)不再有fd个数的上限限制,可以将参数ufds想象成栈低指针,nfds是栈中元素个数,该栈可以无限制增长
(2)引入pollfd结构,将fd信息、需要监控的事件、返回的事件分开保存,则poll返回后不会丢失fd信息和需要监控的事件信息,也就省略了select模型中前面的循环操作,返回后的循环仍然不可避免。另每次poll阻塞操作都会自动把上次的revents清空。
以下是在学习过程中找到的一些好的文章和讨论:
http://bbs3.chinaunix.net/thread-1283223-1-1.html
http://linux.chinaunix.net/techdoc/develop/2008/09/27/1034861.shtml
http://blog.csdn.net/pmunix/archive/2008/01/13/2041512.aspx
http://www.cs.uwaterloo.ca/~brecht/theses/Ostrowski-MMath.pdf