使用非阻塞I/O的应用程序常常使用poll、select和epoll系统调用。poll、select和epoll在本质上有相同的功能:允许一个进程来决定它是否可读或者写一个或多个文件而不阻塞。这些调用也可阻塞进程直到任何一个给定集合的文件描述符可用来读或者写。因此,它们常常用在必须使用多输入输出流的应用程序,而不必粘连在它们任何一个上。epoll 是作为使查询函数扩展到几千个文件描述符的方法。
支持任何一个这些调用都需要来自设备驱动的支持,驱动需要实现poll方法。这个方法的原型如下:
unsigned int (* poll) ( struct file *filp, poll_table *wait );
用户空间程序进行一个poll、select或 epoll系统调用时,这个驱动方法被调用。这个设备驱动方法负责这2步:
1.在一个或多个可指示查询状态变化的等待队列上调用poll_wait。如果没有文件描述符可用作 I/O,内核使这个进程在等待队列上等待所有的传递给系统调用的文件描述符;
2.返回一个位掩码,描述可能不必阻塞就立刻进行的操作。
poll方法的第2个任务是返回位掩码,它描述哪个操作可马上被实现,这也是直接。例如,如果设备有数据可用,一个读可能不必睡眠而完成。poll方法应当指示这个时间状态。在<linux/poll.h>中定义了几个标志:
POLLIN 如果设备可被不阻塞地读,这个位必须设置;
POLLRDNORM 如果“正常”数据可用来读,一个可读的设备返回 (POLLIN | POLLRDNORM)
POLLRDBAND 这个位指示带外数据可用来从设备中读取。
POLLPRI 高优先级数据(带外)可不阻塞地读取。
POLLHUP 当读这个设备的进程见到文件尾, 驱动必须设置 POLLUP.POLLERR 一个错误情况已在设备上发生. 当调用 poll, 设备被报告位可读可写, 因为读写都返回一个错误码而不阻塞. POLLOUT 这个位在返回值中设置, 如果设备可被写入而不阻塞. POLLWRNORM 这个位和 POLLOUT 有相同的含义, 并且有时它确实是相同的数.
一个可写的设备返回( POLLOUT|POLLWRNORM). POLLWRBAND 如同 POLLRDBAND , 这个位意思是带有零优先级的数据可写入设备.
只有 poll 的数据报实现使用这个位, 因为一个数据报看传送带外数据.