2012-09-10 61 views
0

目前我正在用epoll實現一個多線程網絡客戶端應用程序。我的模式很簡單:EPOLLONESHOT返回多個事件

  1. 得到client_fd &寫請求到遠程服務器

  2. 集FD非阻塞&它添加到epfd電(EPOLLIN | EPOLLET | EPOLLONESHOT)等待響應

  3. 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 
} 
+0

你正在測試什麼內核版本? –

+0

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

+0

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

回答

0

我懷疑你有某種錯誤或競爭條件的在你的代碼的某個地方。特別注意你關閉插座的位置。