GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo implementar un tiempo de espera en la llamada a la función de lectura?

Si configura el socket para que opere en modo sin bloqueo, cada llamada para leer leerá solo los datos disponibles actualmente (si los hay). Así que esto es efectivamente igual a un tiempo de espera inmediato.

Puede configurar el modo sin bloqueo en un socket con una función como esta:

int setnonblock(int sock) {
   int flags;
   flags = fcntl(sock, F_GETFL, 0);
   if (-1 == flags)
      return -1;
   return fcntl(sock, F_SETFL, flags | O_NONBLOCK);
}

(Para obtener más información sobre la lectura de sockets sin bloqueo, consulte el read página man)


No dice cuál es el sistema operativo, pero si está ejecutando Linux, puede usar la llamada de selección. Regresa si hay algo para leer en el descriptor del archivo o puede configurarlo para que se agote el tiempo de espera si no hay nada para leer. El código de retorno indica cuál.


Como alternativa a select() , para el caso específico de un puerto serie (terminal) puede usar tcsetattr() para poner el descriptor de archivo en modo no canónico, con un tiempo de espera de lectura.

Para hacer esto, desactive el ICANON marca y establece el VTIME carácter de control:

struct termios termios;

tcgetattr(filedesc, &termios);
termios.c_lflag &= ~ICANON; /* Set non-canonical mode */
termios.c_cc[VTIME] = 100; /* Set timeout of 10.0 seconds */
tcsetattr(filedesc, TCSANOW, &termios);

Nota VTIME se mide en décimas de segundo, y que el tipo utilizado para ello suele ser un unsigned char , lo que significa que el tiempo de espera máximo es de 25,5 segundos.


select() toma 5 parámetros, primero el descriptor de archivo más alto + 1, luego un fd_set para lectura, uno para escritura y otro para excepciones. El último parámetro es una estructura timeval, que se utiliza para el tiempo de espera. Devuelve -1 en caso de error, 0 en tiempo de espera o el número de descriptores de archivo en los conjuntos que están configurados.

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/select.h>

int main(void)
{
  fd_set set;
  struct timeval timeout;
  int rv;
  char buff[100];
  int len = 100;
  int filedesc = open( "dev/ttyS0", O_RDWR );

  FD_ZERO(&set); /* clear the set */
  FD_SET(filedesc, &set); /* add our file descriptor to the set */

  timeout.tv_sec = 0;
  timeout.tv_usec = 10000;

  rv = select(filedesc + 1, &set, NULL, NULL, &timeout);
  if(rv == -1)
    perror("select"); /* an error accured */
  else if(rv == 0)
    printf("timeout"); /* a timeout occured */
  else
    read( filedesc, buff, len ); /* there was data to read */
  close(filedesc);
}

Linux
  1. Cómo arreglar la llamada a la función indefinida apc_fetch () – Error fatal de PHP [Resuelto]

  2. ¿Cómo llamar a una función Bash en Bash Script dentro de Awk?

  3. ¿Cómo configurar un rastreador Bittornado?

  4. ¿Cómo cambiar el tiempo de espera de Grub en Ubuntu 20.04?

  5. Cómo llamar a la función C en C++, función C++ en C (Mezclar C y C++)

Cómo configurar WordPress en una Raspberry Pi

Cómo configurar un trabajo cron en Linux

Cómo leer un archivo línea por línea en Bash

Cómo configurar o cambiar el nombre de host en Linux

Cómo instalar y configurar SeedDMS

¿Cómo aumentar el tiempo de espera en masilla?