select poll epoll 浅析

select poll epoll 浅析

reference:

http://blog.csdn.net/jiange_zh/article/details/50811553

 

1, 三者可以对多个文件描述符进行监听,当ready后可以进行预期的IO操作;

2, select可以处理的event是read/write ready,poll可以处理更加复杂的event POLLIN/POLLOUT(相对于select的readfds,writefds ready)/POLLPRI/POLLRDHUP/POLLERR/POLLHUP/POLLNVAL, epoll在poll的基础上,增加了EPOLLET (edge trigger 边沿触发)和EPOLLONESHOT;

3, select/poll比epoll的效率低,随着fd数量的增加,对比越明显。select/poll每一次poll都会在kernel space遍历所有的文件描述符,epoll是在设备ready(粗略理解成fd ready)后通过回调函数将此fd放到就绪链表中,每次poll将此链表返回;

 

epoll的优势:

1, 在大型服务器上,数以千计的fd需要快速响应,epoll的时间复杂度比select/poll高出数量级,空间复杂度的影响可以忽略;

2, epoll可以通过epoll_ctl函数动态添加/修改/删除,对于不能预期的fd,比较容易添加到poll队列中;(select和poll也可以通过编程手段实现这一点,但自身支持会简化使用场景)

select:

#include <stdio.h>
#include <string.h>
#include <sys/select.h>

int main(void)
{
    int maxfd = 0;
    int ret = -1;
    fd_set rfds;
    struct timeval tv;
    char buf[1024] = {0x0};

    printf("select testing.\n");

    while(1)
    {
        FD_ZERO(&rfds);
        FD_SET(0, &rfds);
        maxfd = 1; /* maxfd = fd + 1*/
        tv.tv_sec = 0;
        tv.tv_usec = 100*1000; /* 100ms. */
        ret = select(maxfd, &rfds, NULL, NULL, &tv);
        if (ret == 0x0)
        {
            //printf("time out.\n");
            continue;
        }
        else if (ret < 0x0)
        {
            perror("select:");
            continue;
        }
        else
        {
            if(FD_ISSET(0, &rfds))
            {
                memset(buf, 0x0, sizeof(buf));
                ret = read(0, buf, sizeof(buf));
                if(0x0 == strncmp(buf, "quit", 4))
                    return 0x0;
                printf("buf:%s", buf);
            }
        }
    }
    
    return 0x0;
}

 

poll:

#include <stdio.h>
#include <poll.h>
#include <errno.h>
#include <string.h>

int main(void)
{
    struct pollfd pfd;
    int ret = -1;
    char buf[1024] = {0x0};
    
    printf("poll testing.\n");
    
    memset(&pfd, 0x0, sizeof(pfd));
    
    pfd.fd = 0;
    pfd.events = POLLIN;
    
    while(1)
    {
        ret = poll(&pfd, 1, 100);
        if(ret == -1 && errno == EINTR)
            continue;

        if(ret < 0)
            perror("poll:");

    if(ret == 0x0)
    {
        //printf("time out!\n");
        continue;
    }

        if(pfd.revents & POLLIN)
        {
            ret = read(pfd.fd, buf, sizeof(buf));
            printf("buf:%s");
            if(0x0 == strncmp("quit", buf, 4))
                return 0x0;
        }
    }

    return 0x0;
}

 

epoll:

#include <stdio.h>
#include <string.h>
#include <sys/epoll.h>

#define MAX_EVENTS (10)

int main(void)
{
    int epfd = -1;
    int ret = -1;
    int fd = -1;
    int i = 0;
    struct epoll_event ev;
    struct epoll_event revs[MAX_EVENTS];
    char buf[1024] = {0x0};

    printf("epoll testing\n");
    
    epfd = epoll_create(1);
    if(epfd < 0x0)
    {
        perror("epoll_create:");
        return -1;
    }
    
    memset(&ev, 0x0, sizeof(ev));
    ev.data.fd = 0;
    ev.events  = EPOLLIN;
    epoll_ctl(epfd, EPOLL_CTL_ADD, 0, &ev);
    
    while(1)
    {
        memset(&revs, 0x0, sizeof(revs));
        ret = epoll_wait(epfd, &revs[0], MAX_EVENTS, 10);
        switch(ret)
        {
            case 0:
            {
                //printf("time out!\n");
                break;
            }

            case -1:
            {
                perror("epoll_wait:");
                break;
            }

            default:
            {
                for(i = 0; i < ret; i++)
                {
                    fd = revs[i].data.fd;
                    if(revs[i].events & EPOLLIN)
                    {
                        memset(buf, 0x0, sizeof(buf));
                        ret = read(fd, buf, sizeof(buf));
                        if(0x0 == strncmp(buf, "quit", 4))
                            return 0x0;
                        printf("buf:%s", buf);
                    }
                }
            }
        }
    }
    
    return 0x0;
}

 

posted @ 2018-02-05 17:40  xinpengc  阅读(281)  评论(0编辑  收藏  举报