用poll实现多路复用

为了实现高效率的多路传输,Linux提供了一个系统调用poll ,允许进程在多个文件符之间同时阻塞。
进程不再需要不断的检查每个文件的文件描述符,而是通过一个系统调用来指定要读取或写入的文件描述符。
当有一个或多个文件数据可以读出或可以写入时,poll函数就返回,然后应用程序就可以读写这些文件描述符而不用担心阻塞。
当这些文件被处理完毕后,进程发起另外一个poll调用,一直阻塞,直到一个文件可以被读写到时,poll开始返回。

函数头文件
#include < sys/poll.h>
函数原型
int poll(struct pollfd *fds,int numfds,int timeout);
参数说明:
fds 描述那些文件描述符以及哪种类型的i/o需要被监控。

  struct pollfd{
		int fd;
		short events;
		short revents;
	}

events:
POLLIN:有普通文件可以从文件操作符中读取;
POLLPRI:有优先级数据可以读取;
POLLOUT:可以向文件操作符中写入数据;
POLLERR:在文件描述符上有一个未解决的错误,针对该文件描述符的系统调用将会使errno被设置为适当的值;
POLLHUP:文件连接被断开,不能再写入数据;
POLLNVAL:文件描述符不合法;
numfds:指定第一个参数中数组的数目
timeout:poll需要多长时间来等待一个事件的发生,如果0 那么代表超时时间为无限大及不会超时
返回值:
如果超时则返回0,发生错误则返回-1,正确则返回大于0的正整数。


采用poll解决两个管道及多个管道的读操作,无论可以任何一个管道发生数据变化时,poll模式都可以监控获取到管道的变化,不用不断的检查文件描述符的变化,
通过这种方式可以降低系统的负载。

例:

  #include "fcntl.h"
  #include "stdio.h"
  #include "sys/poll.h"
  #include "unistd.h"
  
  int main(void){
    struct pollfd fds[2]; //申明两个poll文件描述符
    char buf[4096];
    
    int r,rc;
     
    //打开两个管道文件
    if((fds[0]=open("p1",O_RDONLY|O_NONBLOCK))<0){
 	 printf("打开管道p1失败!\n");
	 return 0;
	}  
    if((fds[1]=open("p2",O_RDONLY|O_NONBLOCK))<0){
	printf("打开管道p2失败!\n");
	return 0;
	}
	

    fds[0].events  = POLLIN;
    fds[1].events  = POLLIN;
     
    //阻塞等待
   
    while(fds[0].events || fds[1].events ){
       //开始读取文件start
       for(i =0;i<2;i++){
           if(fds[i].events){
			rc = read(fds[i].fd,buf,sizeof(buf));
			if(rc <0){
				printf("文件读取失败!\n");
				return 0;
			}else{
				buf[rc] ='\0';
				printf("读取信息:%s\n",buf);
			}		
		}
        }
       //开始读取文件end  
    }
    return 0;
  }


综上所述:
poll方式是一种多路阻塞的读取机制。