0

現在、epoll を使用してマルチスレッド ネットワーク クライアント アプリケーションを実装しています。私のモデルは単純です:

  1. client_fd を取得し、リクエストをリモート サーバーに書き込みます

  2. fd ノンブロッキングを設定し、それを epfd(EPOLLIN|EPOLLET|EPOLLONESHOT) に追加して応答を待ちます

  3. fd から EPOLLIN を取得し、応答全体を読み取り、リソースを解放します

私が遭遇する問題は、同じ fd で複数の EPOLLIN を取得することがあります ( BY USING EPOLLIN|EPOLLET|EPOLLONESHOT )。最初の EPOLLIN evt ですべてのリソース (client_fd を含む) を解放したため、2 番目の 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
}
4

1 に答える 1

0

コードのどこかに何らかのバグまたは競合状態があると思われます。特にソケットを閉じる場所に注意してください。

于 2012-09-11T18:04:18.640 に答える