- 论坛徽章:
- 0
|
个人使用epoll做一个多线程的网络服务,模型简单:
1,获取fd,从fd写入请求,然后在该fd上注册EPOLLIN事件,然后将fd放入epoll(EPOLLIN|EPOLLET|EPOLLONESHOT),等待服务器端返回。
2,服务器端返回EPOLLIN事件之后,在fd上读取请求,处理之后释放所有资源以及该fd。
现在问题是,发现有一定概率在这个fd返回EPOLLIN并且读取成功和释放资源之后,这个fd上又会产生一个EPOLLIN事件(我明明已经使用EPOLL_CTL_DEL在epfd上面删除了这个fd了。。),然后由于资源已经被释放掉饿,我的程序就挂了。。。
哪位大神可以告诉我下为啥会发生这么诡异的事情呢。。。
下面是代码片段:
//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
} |
|