使用select(...)作为事件驱动的循环?

时间:2012-05-23 18:32:33

标签: c select

...
/* Initialize the input set */
FD_ZERO(&input);
FD_SET(fd, &input);
FD_SET(sock, &input);

max_fd = (sock > fd ? sock : fd) + 1;

/* Do the select */
n = select(max_fd, &input, NULL, NULL, NULL);

/* See if there was an error */
if (n < 0)
  perror("select failed");
else if (n == 0)
  puts("TIMEOUT");
else
{
  /* We have input */
  if (FD_ISSET(fd, &input))
process_fd();
  if (FD_ISSET(sock, &input))
process_socket();
}

我想知道,只要其中一个描述符准备好,这种方法就不会退出 如果我想读两个描述符怎么办?

我仍然希望使用select(...)来确定哪个首先准备好先处理。 我尝试将整个事情放在一个循环中,但它会永远阻止。


更新

  328     fd_set readfds; FD_ZERO(&readfds);
  329     int waiting = 2;
  330     while(waiting) {
  331 
  332       FD_SET(sockv4query, &readfds);
  333       FD_SET(sockv6query, &readfds);
  334 
  335       /* one greater than the highest fd number */
  336       int nfds = (sockv4query > sockv6query ? sockv4query : sockv6query) + 1;
  337 
  338       if (
  339          select(
  340                  nfds,         /* number of fds */
  341                  &readfds,     /* set of read fds */
  342                  NULL,         /* set of write fds */
  343                  NULL,         /* set of exception fds */
  344                  NULL          /* maximum wait interval */
  345                ) < 0
  346        ) {
  347         perror("select(...)");
  348         continue;
  349       } else {
  350 
  351         /* one or more descriptors is ready */
  352         if(FD_ISSET(sockv4query, &readfds)) {
  353           receive_response_and_echo(sockv4query);
  354           waiting -= 1;
  355         }
  356         if(FD_ISSET(sockv6query, &readfds)) {
  357           receive_response_and_echo(sockv6query);
  358           waiting -= 1;
  359         }
  360       }
  361     }

1 个答案:

答案 0 :(得分:0)

我会做类似的事情。

      328     fd_set readfds; FD_ZERO(&readfds);
      329     int process_fd1 = 1,process_fd2 = 1;
      330     while(process_fd1 || process_fd2) {
      331 
      332       FD_SET(sockv4query, &readfds);
      333       FD_SET(sockv6query, &readfds);
      334 
      335       /* one greater than the highest fd number */
      336       int nfds = (sockv4query > sockv6query ? sockv4query : sockv6query) + 1;
      337 
      338       if (
      339          select(
      340                  nfds,         /* number of fds */
      341                  &readfds,     /* set of read fds */
      342                  NULL,         /* set of write fds */
      343                  NULL,         /* set of exception fds */
      344                  NULL          /* maximum wait interval */
      345                ) < 0
      346        ) {
      347         perror("select(...)");
      348         continue;
      349       } else {
      350 
      351         /* one or more descriptors is ready */
      352         if(FD_ISSET(sockv4query, &readfds)) {
      353           receive_response_and_echo(sockv4query);
      354           process_fd1 = 0;
      355         }
      356         if(FD_ISSET(sockv6query, &readfds)) {
      357           receive_response_and_echo(sockv6query);
      358           process_fd2 = 0;
      359         }
      360       }
      361     }