簡體   English   中英

epoll(EPOLLET)取決於讀取字節數?

[英]epoll (EPOLLET) depends on count of read bytes?

我在邊緣觸發模式下使用epoll。 為了避免飢餓,代碼從一個套接字一次讀取MAX_FREAD_LENGTH個字節。 之后組裝片段直到EOL發生。 我注意到當MAX_FREAD_LENGTH很小時epoll卡住了。 我認為它適用於任何大小的讀取塊。 它適用於512字節,但有時掛起(意味着沒有EPOLLIN事件)。 如果我遞增MAX_FREAD_LENGTH,它會變得更穩定。 我該如何解決這個問題?

非常感謝您考慮我的問題!

EPOLL初始化

int res;
epFd = epoll_create(EPOLL_SIZE);
event.data.fd = serverFd;
event.events = EPOLLIN|EPOLLET;
res=epoll_ctl(epFd, EPOLL_CTL_ADD, serverFd, &event);
if (res == -1){
  perror ("epoll_ctl error: ");
  return EH_ERROR;
}
events = calloc (MAX_EVENTS, sizeof event);

注冊網絡事件:

while (TRUE){
  int nfds;
  do{
    nfds = epoll_wait(epFd, events, MAX_EVENTS, -1);
  } while (nfds < 0 && errno == EINTR);

  int i = 0;
  for (;i<nfds;i++){
    if ( (events[i].data.fd == serverFd) && (events[i].events & EPOLLIN)){
      if ((clientFd = accept(serverFd,(struct sockaddr *) &clientAddr, &clientLen)) < 0){
        char log[255];
        sprintf(log,"dispatch_net_event: Socket accept failed: %s",strerror(errno));
        logger->log(LOGG_ERROR,log);
      }
      if(newclient(clientFd)!=EH_ERROR){
        /* client created */
        setnonblocking(fd,NONBLOCKING);
        event.data.fd = clientFd;
        event.events = EPOLLIN |EPOLLET;
        if(epoll_ctl(epFd, EPOLL_CTL_ADD, fd, &event)<0){
          fprintf(stderr,"Epoll insertion error (fd=%d): ",clientFd);
          return EH_ERROR;             
        }    
        continue;
      }
      else{
        logger->log(LOGG_ERROR,"Client creation error");
        continue;
      }
    }
    else{
     dispatch_event(events[i].data.fd,NET_EVENT);
    }
  }
}

處理網絡事件

#define SMTP_MAX_LINE_LENGTH MAX_FREAD_LENGTH
ssize_t count;
char buf[SMTP_MAX_LINE_LENGTH];

memset(buf,'\0', SMTP_MAX_LINE_LENGTH);
count = read (fd, buf,MAX_FREAD_LENGTH );

if (count==-1){
  if (errno == EAGAIN)
    return KEEP_IT;
  else if (errno == EWOULDBLOCK)
    return KEEP_IT;
  else{
    char log[255];
    sprintf(log,"handle_net_event: Read error: %s",strerror(errno));
    logger->log(LOGG_ERROR,log);
  }
}
else{   /* count > 0 there are data in the buffer */
  /* assemble possible partial lines, TRUE if line is whole (end with \r\n)*/
  whole=assemble_line(count,client,&buf[0]);
}
 /* process the line */

編輯:

我忘了提到,epoll在一個單獨的線程中運行,而不是其他部分

我認為你錯誤地使用了EPOLLET。 嘗試沒有EPOLLET(即使用水平觸發模式),看看是否有效。 如果是這樣,這意味着你的基本問題是你沒有做邊緣觸發模式要求,即繼續讀取任何准備好的描述符,直到你獲得EAGAIN。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM