0
目前我正在用epoll实现一个多线程网络客户端应用程序。我的模式很简单:EPOLLONESHOT返回多个事件
得到client_fd &写请求到远程服务器
集FD非阻塞&它添加到epfd电(EPOLLIN | EPOLLET | EPOLLONESHOT)等待响应
GET来自fd的EPOLLIN,读取整个响应并释放资源
问题我遇到的情况是,偶尔我会在同一个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
}
你正在测试什么内核版本? –
Linux版本2.6.9xenu_7-0-0-0(gcc版本3.4.5 20051201(红帽3.4.5-2))#5 SMP Thu Sep 16 22:15:55 CST 2010 – elvis
Linux版本2.6.9_5-9 -0-0(gcc版本3.4.4 20050721(红帽3.4.4-2))#1 SMP Wed Jun 23 14:03:19 CST 2010 – elvis