Pergunta

Eu estou usando select() em uma plataforma Linux / ARM para ver se um soquete udp recebeu um pacote. Eu gostaria de saber quanto tempo foi permanecendo na chamada seleção se ele retorna antes do tempo limite (tendo detectado um pacote).

Algo ao longo das linhas de:

int wait_fd(int fd, int msec)
{
    struct timeval tv;
    fd_set rws;

    tv.tv_sec = msec / 1000ul;
    tv.tv_usec = (msec % 1000ul) * 1000ul;

    FD_ZERO( & rws);
    FD_SET(fd, & rws);

    (void)select(fd + 1, & rws, NULL, NULL, & tv);

    if (FD_ISSET(fd, &rws)) { /* There is data */
        msec = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
        return(msec?msec:1);
    } else { /* There is no data */
        return(0);
    }
}
Foi útil?

Solução

A coisa mais segura é ignorar a definição ambígua de select() e tempo-lo sozinho.

Apenas obter o tempo antes e depois do select e subtrair que a partir do intervalo que você queria.

Outras dicas

Se bem me lembro, o select () função trata o tempo limite e um parâmetro de I / O e quando SELECT retorna o tempo restante é devolvido na variável tempo limite.

Caso contrário, você terá que registrar o tempo atual antes de chamar, e novamente depois e obter a diferença entre os dois.

De "homem selecione" no OSX:

 Timeout is not changed by select(), and may be reused on subsequent calls, however it 
 is good style to re-ini-tialize it before each invocation of select().

Você precisa chamar gettimeofday antes de chamar select, e depois gettimeofday na saída.

[Edit] Parece que o Linux é um pouco diferente:

   (ii)   The select function may update the timeout parameter to indicate
          how much time was left. The pselect  function  does  not  change
          this parameter.

   On Linux, the function select modifies timeout to reflect the amount of
   time not slept; most other implementations do not do this.  This causes
   problems  both  when  Linux code which reads timeout is ported to other
   operating systems, and when code is  ported  to  Linux  that  reuses  a
   struct  timeval  for  multiple selects in a loop without reinitializing
   it.  Consider timeout to be undefined after select returns.

Linux select () atualiza o argumento de tempo limite para refletir o tempo que tem passado.

Note que este não é portátil através de outros sistemas (daí o aviso no manual OS X citado acima), mas funciona com Linux.

Gilad

Não use escolha, tente com fd maior que 1024 com o seu código e ver o que você vai conseguir.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top