GNU/Linux >> Tutoriels Linux >  >> Linux

Comment implémenter un délai d'attente dans l'appel de la fonction de lecture ?

Si vous configurez le socket pour qu'il fonctionne en mode non bloquant, chaque appel à read ne lira que les données actuellement disponibles (le cas échéant). Cela équivaut donc effectivement à un délai d'attente immédiat.

Vous pouvez définir le mode non bloquant sur un socket avec une fonction comme celle-ci :

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);
}

(Pour plus d'informations sur la lecture à partir de sockets non bloquants, consultez le read page de manuel)


Vous ne dites pas quel est le système d'exploitation, mais si vous utilisez Linux, vous pouvez utiliser l'appel select. Il renvoie s'il y a quelque chose à lire sur le descripteur de fichier ou vous pouvez le configurer pour qu'il expire s'il n'y a rien à lire. Le code de retour indique lequel.


Comme alternative à select() , pour le cas particulier d'un port série (terminal) vous pouvez utiliser tcsetattr() pour mettre le descripteur de fichier en mode non canonique, avec un délai de lecture.

Pour cela, désactivez le ICANON drapeau et définissez le VTIME caractère de contrôle :

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);

Remarque VTIME est mesuré en dixièmes de seconde, et que le type utilisé pour cela est généralement un unsigned char , ce qui signifie que le délai maximal est de 25,5 secondes.


select() prend 5 paramètres, d'abord le descripteur de fichier le plus élevé + 1, puis un fd_set pour la lecture, un pour l'écriture et un pour les exceptions. Le dernier paramètre est une structure timeval, utilisée pour le timeout. Il renvoie -1 en cas d'erreur, 0 en cas d'expiration du délai ou le nombre de descripteurs de fichiers dans les ensembles définis.

#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. Comment configurer le tunnel SSH

  2. Pkexec - Comment définir un délai d'expiration personnalisé pour Auth_admin_keep lors de l'écriture d'une politique Pkexec ?

  3. Comment configurer un tracker Bittornado ?

  4. Comment appeler la fonction C en C++, la fonction C++ en C (mélanger C et C++)

  5. Quand vérifier EINTR et répéter l'appel de fonction ?

Comment configurer WordPress sur un Raspberry Pi

Comment configurer une tâche Cron sous Linux

Comment lire un fichier ligne par ligne dans Bash

Comment définir ou modifier le nom d'hôte sous Linux

Comment installer et configurer SeedDMS

Comment augmenter le délai d'attente dans le mastic?