本帖最后由 lonerzf 于 2014-7-27 21:36 编辑
这一帖主要记录linux的I/O复用学习。主要内容有select,poll,epoll用法。
今儿个先记录poll 函数
主要参考文献: blog.csdn.net/mybelief321/article/details/8997596
blog.csdn.net/ithomer/article/details/6126712
blog.csdn.net/blueboy2000/article/details/4485874
一、Linux下五种I/O模型
1、阻塞I/O模型 最流行的I/O模型是阻塞I/O模型,缺省情形下,所有套接口都是阻塞的。我们以数据报套接口为例来讲解此模型(我们使用UDP而不是TCP作为例子的原因在于就UDP而言,数据准备好读取的概念比较简单:要么整个数据报已经收到,要么还没有。然而对于TCP来说,诸如套接口低潮标记等额外变量开始活动,导致这个概念变得复杂)。 进程调用recvfrom,其系统调用直到数据报到达且被拷贝到应用进程的缓冲区中或者发生错误才返回,期间一直在等待。我们就说进程在从调用recvfrom开始到它返回的整段时间内是被阻塞的。 2、非阻塞I/O模型 进程把一个套接口设置成非阻塞是在通知内核:当所请求的I/O操作非得把本进程投入睡眠才能完成时,不要把本进程投入睡眠,而是返回一个错误。也就是说当数据没有到达时并不等待,而是以一个错误返回。 3、I/O复用模型 调用select或poll,在这两个系统调用中的某一个上阻塞,而不是阻塞于真正I/O系统调用。 阻塞于select调用,等待数据报套接口可读。当select返回套接口可读条件时,调用recevfrom将数据报拷贝到应用缓冲区中。 4、信号驱动I/O模型 首先开启套接口信号驱动I/O功能, 并通过系统调用sigaction安装一个信号处理函数(此系统调用立即返回,进程继续工作,它是非阻塞的)。当数据报准备好被读时,就为该进程生成一个 SIGIO信号。随即可以在信号处理程序中调用recvfrom来读数据报,井通知主循环数据已准备好被处理中。也可以通知主循环,让它来读数据报。 5、异步I/O模型 告知内核启动某个操作,并让内核在整个操作完成后(包括将数据从内核拷贝到用户自己的缓冲区)通知我们。 这种模型与信号驱动模型的主要区别是:
信号驱动I/O:由内核通知我们何时可以启动一个I/O操作,
异步I/O模型:由内核通知我们I/O操作何时完成。
二、I/O复用的典型应用场合 1、当客户处理多个描述字(通常是交互式输入和网络套接口)时,必须使用I/O复用。 2、如果一个服务器要处理多个服务或者多个协议(例如既要处理TCP,又要处理UDP),一般就要使用I/O复用。
三、poll函数的实验
pollfd中的events请预先设置。可选值如下: 当poll()函数返回正值时,代表满足响应事件的文件描述符的个数,如果返回0则代表在规定事件内没有事件发生。如发现返回为负则应该立即查看 errno,因为这代表有错误发生。 如果没有事件发生,revents会自动被清空。
程序流程图如下:
实验代码如下:
操作方法:
先在工作目录下新建in1和in2两个管道文件。
mknod in1 p
mknod in2 p
执行程序 ./multiplex_poll
打开新的终端并进入工作目录,输入cat > in1
然后再键入字符,会发现终端1会显示当前终端输入的字符,程序正确。
四、小结
这一节只记录poll,还有select 下节继续。
|