ubuntu下c++ select与epoll函数

本文对比分析了select和epoll两种IO多路复用技术在服务器并发处理中的作用与实现方式。select通过轮询机制监测多个套接字的状态,而epoll则能更高效地返回所有需要响应的套接字,避免了不必要的访问,适用于高并发场景。

select和epoll

概念

select和epoll都归属于IO多路复用是一种代替多线程实现服务器并发的方案。举个例子,假设小明要来8公寓找小果,但是不知道他在哪个寝室,但是每个寝室都分配了一个女仆阿姨,小果的阿姨一眼看到了小明,就把他叫到小果那里了;过了一阵子学校没钱了,只雇佣了一个阿姨,小明找不到小果,阿姨就挨个屋子问小果在哪里直到找到小果或者查无此人来错公寓嘞您;又过了一阵子,学校管理升级阿姨直接用花名册就能找到每个同学的宿舍。OK多线程select和epoll正好对应这三种情况,多线程就是为所有链接的套接字安排一个线程负责信息的收发;select基于轮询的思想,对所有需要判断的套接字分别询问是否需要响应;epoll可以直接返回一个数组,其中保存的就是所有需要响应的套接字,不需要像select那样做多余的访问过程。

select

set<int> fd;//加入需要监听的套接字
timeval timeout = {0};
timeout.tv_usec = usec;
FD_ZERO(&fds);
int maxfd = 0;
for(int i:fd){
    maxfd = maxfd>i?maxfd:i;
    FD_SET(i,&fds);
}
switch(select(maxfd+1,&fds,NULL,NULL,&timeout)){
    case -1:{
        cout<<"select error";
        exit(1);
    }case 0:break;
    default:{
        for(int i:fd){
            if(FD_ISSET(i,&fds)){
                //处理套接字i的过程
            }
        }
    }
}

epoll

void listen_loop(unsigned int sock_fd)
{
    int epollfd, i, ret;
    int timeout = 300;
    struct epoll_event event;
    struct epoll_event eventList[10];

    /*创建epoll监听事件*/
    epollfd = epoll_create(10);
    event.events = EPOLLIN | EPOLLET;
    event.data.fd = sock_fd;

    /*注册epoll监听事件.*/
    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, sock_fd, &event) < 0) {
        printf("register epoll event err !");
        return;
    }

    while (1) {
    	//ret为个数
        ret = epoll_wait(epollfd, eventList, 10, timeout);

        /*epoll事件错误.*/
        if (ret < 0) {
            printf("epoll event err!");
            break;
        }
        /*无事件返回.*/
        else if (ret == 0) {
            continue;
        }

        /*epoll返回事件.*/
        for (i = 0; i < ret; i++) {
            /*epoll 错误*/
            if ((eventList[i].events & EPOLLERR) || (eventList[i].events & EPOLLHUP) || !(eventList[i].events & EPOLLIN)) {
				//错误
				exit(1);
            }

            //half connection
            if (eventList[i].events & EPOLLRDHUP) {
            	//客户端关闭socket
                close(eventList[i].data.fd);
            }

            /*accept事件*/
            if (eventList[i].data.fd == sock_fd) {
                //等于服务器socket 处理连接
            }
            /*非sock_fd则为其他事件.*/
            else {
            	//否则为client的socket接受信息
            }
        }
    }
    close(epollfd);
    close(sock_fd);
    return;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值