poll() & struct pollfd &event 介绍

struct pollfd 介绍:

结构介绍:

struct pollfd{
    int fd; /*文件描述符,如建立socket后获取的fd, 此处表示想查询的文件描述符*/
    short events;	/*等待的事件,就是要监测的感兴趣的事情*/
    short revents;	/*实际发生了的事情*/
};

poll() 函数介绍

简要说明:

poll() 函数是linux 中的字符设备驱动中的一个函数,poll被epoll() 取代,和slect 实现的功能差不多。

poll()函数的作用是把当前的文件指针挂到等待队列中。

结构介绍:

int poll(struct pollfd *fds, unsigned int nfds, int timeout) 

参数介绍:

pollfd *fds : 指向pollfd结构体数组,用于存放需要检测器状态的Socket 描述符或其它文件描述符。

unsigned int nfds: 指定pollfd 结构体数组的个数,即监控几个pollfd.

timeout:指poll() 函数调用阻塞的时间,单位是ms.如果timeout=0则不阻塞,如timeout=INFTIM 表 示一直阻塞直到感兴趣的事情发生。

返回值:>0 表示数组fds 中准备好读,写或出错状态的那些socket描述符的总数量

​ ==0 表示数组fds 中都没有准备好读写或出错,当poll 阻塞超时timeout 就会返回。

​ -1 表示poll() 函数调用失败,同时回自动设置全局变量errno.

函数特点:

  • 每当函数调用后,不会清空这个fds指向的数组,适用于大量socket 描述符的情况。而select()函数调用后会清空它所检测的socket描述符集合,因此select()只是用检测一个socket 描述符的情况。
  • 如果待监测的socket 描述符为负值,则这个描述符的检测就会被忽略,poll()函数返回时直接把revents 设置为0
  • 该poll()函数不会受到socket 描述符上的O_NDELAY 标记和O_NONBLOCK 标记的影响。

使用举例:

  • 常用事件标记:POLLIN/POLLRDNORM(可读),POLLOUT/PILLWRNORM(可写),POLLEER(出错)。
#define FDS_INDEX 3;
#define FDS_TIMEOUT 30;
#define BUFFER_LEN (1024<<3);
#define INVALID_FD (-1);

int main()
{
    strcut pollfd fds[FDS_INDEX];
    int ret_value=0;
    char * read_buffer=NULL;
    int read_lean=0;
    int poll_running=1;
	int fd0=INVALID_FD;
    int fd1=INVALID_FD;
    int fd2=INVALID_FD;
	char *fd1_path="/media/flash/nvm/test1.cpp";
	char *fd2_path="media/flash/nvm/test2.cpp" 
	
    fd0=initsocket() // exe initsocket() will get socket fd
	if((fd1=open(fd1_path,O_RDONLY)<0)
	{
   	 return -1;
	}
    if((fd2=open(fd2_path,O_RDONLY)<0)
	{
   	 return -1;
	}
	
     fds[0].fd=fd0;
     fds[1].fd=fd1;
     fds[2].fd=fd2;
     for(int i=0;i<FDS_INDEX;i++)
     {
     	fds[i].events=POLLIN          
     }
     
     read_buffer=(cahr*)malloc(BUFFER_LEN);
     while(poll_running)
     {
        ret_value=poll(fds,FDS_INDEX,FDS_TIMEOUT);
        if(ret_value==0)
        	continue;
         else if(ret_value<0)
         {
             printf("poll exe error\n");
             break;
         }
         else
         {
             if((fds[0].revent & POLLIN)==POLLIN)
             {
                 /*检测到可往从socket中读取数据*/
                 read_len=read(fds[0].fd,read_buffer,BUFFER_LEN);
                 if(read_len)
                 {
                    /* 数据读取在read_buffer 中*/ 
                     
                 }
                 
             }
             
             if((fds[1].revent & POLLIN)==POLLIN)
             {
                 /*检测到可往从socket中读取数据*/
             }
             
             if((fds[2].revent & POLLIN)==POLLIN)
             {
                 /*检测到可往从socket中读取数据*/
                 
             }       
         }
/*
//多个事件之间使用按位或操作
fds[index].event=POLLIN|POLLOUT|POLLERR;
if(fds[index].revent & POLLOUT)==POLLOUT{
    /*  检测到可以往socket 中写数据*/
    //发送数据。。
 */   
   if(fd0>0)
       close(fd0);
   if(fd1>0)
       close(fd1);
    if(fd2>0)
        clsoe(fd2);
    fd0=INVALID_FD;
    fd1=INVALID_FD;
    fd2=INVALID_FD; 
         
     if(read_buffer!=NULL)
         free(read_buffer);
         
   return 0;
}

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐