poll实现I/O多路复用

来源:互联网 发布:软件项目计划安排 编辑:程序博客网 时间:2024/06/05 01:51

poll函数原型


参数说明:

fds:是一个struct pollfd结构类型的数组,用于存放需要检测其状态的Socket描述符;每当调用这个函数之后,系统不会清空这个数组,操作起来比较方便;特别是对于socket连接比较多的情况下,在一定程度上可以提高处理的效率;这一点与select()函数不同,调用select()函数之后,select()函数会清空它所检测的socket描述符集合,导致每次调用select()之前都必须把socket描述符重新加入到待检测的集合中;因此,select()函数适合于只检测一个socket描述符的情况,而poll()函数适合于大量socket描述符的情况;

nfds:nfds_t类型的参数,用于标记数组fds中的结构体元素的总数量;

timeout:是poll函数调用阻塞的时间,单位:毫秒;

如果timeout==0,那么poll() 函数立即返回而不阻塞,如果timeout==INFTIM(宏 表示为-1),那么poll() 函数会一直阻塞下去,直到所检测的socket描述符上的感兴趣的事件发生是才返回

函数返回值:

    poll函数的返回值与select函数的返回值一样。

    若返回0:表示超时

    若为-1:错误

    若>0:返回就绪事件的个数

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<poll.h>int main(int argc,char* argv[]){//    if(argc !=3)//    {//        printf("Usage #: %s [ip] [port]\n",argv[0]);//        exit(1);//    }    //创建数组,用以指定我们感兴趣的文件描述符上发生的可读、可写和异常等事件//    struct pollfd//    {//      int fd; //件描述符//      short events; //注册的事件//      short revents; //``实际发生的事件,由内核填充,输出型//    };    struct pollfd fds[2]; //文件描述符    fds[0].fd=0;    fds[0].events=POLLIN; //对读事件感兴趣    fds[0].revents=0;//输出型    fds[1].fd=1;    fds[1].events=POLLOUT;//对写事件感兴趣    fds[1].revents=0;    char buf[1024];    int done=0;    int i=0;    int timeout=5000;//5000毫秒,即5秒    while(!done)    {        int ret=poll(fds,sizeof(fds)/sizeof(fds[0]),timeout);        switch(ret)        {            case -1:                perror("poll");                exit(2);                break;            case 0:                printf("timeout...\n");                break;            default:                //有事件就绪,但还需判断是哪个文件描述符的什么事件                for(i=0;i<sizeof(fds)/sizeof(fds[0]);++i)                {                    //是否可读                    //fds[i]所关心的事件是读,而是有读事件发生                    if(fds[i].fd==0&&(fds[i].revents & POLLIN))                    {                        memset(buf,'\0',sizeof(buf));                        ssize_t _s=read(0,buf,sizeof(buf)-1);                        if(_s>0)                        {                            buf[_s -1]='\0';                            if(strncmp(buf,"quit",4)==0)                            {                                close(fds[i].fd);                                exit(0);                            }                            printf("echo#:%s\n",buf);                        }                    }                     if(fds[i].fd==1&&(fds[i].revents & POLLOUT))                    {                        memset(buf,'\0',sizeof(buf));                        strcpy(buf,"mengxiangjia");                        printf("echo#:%s\n",buf);                        sleep(3);                    }                }                break;        }    }    return 0;}


poll函数的缺点:

(1)大量的fd的数组被整体复制于用户态和内核地址空间之间,而不管这样的复制是不是有意义。

(2)与select一样,poll返回后,需要轮询poolfd来获取就绪的描述符。


poll函数的优点:

(1)poll函数不要求计算最大文件描述符的大小

(2)poll函数在应付大数目的文件描述符的时候速度更快,相比于select

(3)它没有最大连接数的限制,原因是它基于链表来存储的。


0 0
原创粉丝点击