EPOLLONESHOT返回多个事件

时间:2012-09-10 02:33:23

标签: multithreading epoll

目前我正在使用epoll实现muliti-thread网络客户端应用程序。我的模型很简单:

  1. 获取client_fd&向远程服务器写入请求

  2. 设置fd nonblocking&将它添加到epfd(EPOLLIN | EPOLLET | EPOLLONESHOT)等待回复

  3. 从fd获取EPOLLIN,阅读整个响应并释放资源

  4. 我遇到的问题偶尔我会在同一个fd上获得多个EPOLLIN(使用EPOLLIN | EPOLLET | EPOLLONESHOT )。由于我在第一个EPOLLIN evt发布了所有资源(包括client_fd),第二个evt崩溃了我的程序。

    强烈赞赏任何建议:)

    以下是代码段:

    //multi-thread wait on the sem, since there should be only one thread 
    //at epoll_wait at the same time(L-F model)
    sem_wait(wait_sem); 
    
    int nfds = epoll_wait(epoll_fd,evts,max_evt_cnt,wait_time_out);
    
    //leader got the fds to proceed
    for(int i =0; i < nfds; ++i){
        io_request* req = (io_request*)evts[i].data.ptr;
        int sockfd = req->fd;
        if(evts[i].events & EPOLLIN){
            ev.data.fd=sockfd;
            if(0!=epoll_ctl(epoll_fd,EPOLL_CTL_DEL,sockfd,&ev)){
                switch(errno){
                    case EBADF:
                        //multiple EPOLLIN cause EPOLL_CTL_DEL fail
                        WARNING("delete fd failed for EBADF");
                        break;
                    default:
                        WARNING("delete fd failed for %d", errno);
                }
             }
             else{
                    //currently walk around by just ignore the error fd
                    crt_idx.push_back(i);
             }
        }
    }
    
    if(crt_idx.size() != nfds)//just warning when the case happen
        WARNING("crt_idx.size():%u != nfds:%d there has been some error!!", crt_idx.size(), nfds);
    
    //current leader waked up next leader, and become a follower
    sem_post(wait_sem);
    
    for(int i = 0; i < crt_idx.size(); ++i)
    {
        io_request* req = (io_request*)evts[crt_idx[i]].data.ptr;
        ...do business logic...
        ...release the resources & release the client_fd
    }
    

1 个答案:

答案 0 :(得分:0)

我怀疑你的代码中某处有某种bug或竞争条件。特别注意关闭插座的位置。