GNU/Linux >> Znalost Linux >  >> Linux

Jak implementovat časový limit ve volání funkce čtení?

Pokud nastavíte, aby soket fungoval v neblokujícím režimu, každé volání ke čtení přečte pouze aktuálně dostupná data (pokud existují). To se tedy v podstatě rovná okamžitému časovému limitu.

Na zásuvce můžete nastavit neblokovací režim pomocí funkce, jako je tato:

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

(Další informace o čtení z neblokujících soketů naleznete v read manuálová stránka)


Neříkáte, jaký je operační systém, ale pokud používáte Linux, můžete použít volání select. Vrátí se, pokud je v deskriptoru souboru něco ke čtení, nebo jej můžete nastavit tak, aby vypršel časový limit, pokud není co číst. Návratový kód označuje který.


Jako alternativa k select() , pro konkrétní případ sériového portu (terminálu) můžete použít tcsetattr() přepne deskriptor souboru do nekanonického režimu s časovým limitem čtení.

Chcete-li to provést, zrušte nastavení ICANON příznak a nastavte VTIME řídicí znak:

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

Poznámka VTIME se měří v desetinách sekundy a typ používaný pro tento typ je obvykle unsigned char , což znamená, že maximální časový limit je 25,5 sekundy.


select() bere 5 parametrů, nejprve nejvyšší deskriptor souboru + 1, pak fd_set pro čtení, jeden pro zápis a jeden pro výjimky. Posledním parametrem je struct timeval, používaný pro časový limit. Vrátí -1 při chybě, 0 při časovém limitu nebo počtu deskriptorů souborů v sadách, které jsou nastaveny.

#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. Jak nastavit reverzní proxy Nginx

  2. Proměnné prostředí Linux:Jak číst a nastavovat na Linux VPS

  3. Jak opravit volání nedefinované funkce apc_fetch() – Závažná chyba PHP [Vyřešeno]

  1. Jak nastavit SSH tunelování

  2. Pkexec – Jak nastavit vlastní časový limit pro Auth_admin_keep při psaní zásad Pkexec?

  3. Jak nastavím výchozí přezdívku pro nová připojení irssi?

  1. Jak volat funkci Bash ve skriptu Bash uvnitř Awk?

  2. Jak nastavit Bittornado Tracker?

  3. Jak změnit časový limit Grub v Ubuntu 20.04?