2012-05-23 3 views
1
... 
/* 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 (...) как цикл, управляемый событиями?

Я все еще хочу использовать select(...), чтобы выяснить, что готово для первого. Я попытался положить все это в цикл, но затем он блокируется навсегда.


UPDATE

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

Используйте цикл for, который повторяется только дважды? –

+0

, но что, если оба дескриптора готовы к самому первому (...), то вторая итерация делает блок select (...) вечно. –

+2

Это обычный способ делать вещи с выбором - вторая итерация будет блокироваться только до тех пор, пока не появится больше доступных данных. Обратите внимание, что вам нужно переустановить 'input' перед вызовом' select' каждой итерации цикла, поэтому вам нужно поместить ВСЕ ваш код в цикл, а не только некоторые из них. –

ответ

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  } 
Смежные вопросы