Comment lire en permanence la FIFO en C

Je veux lire constamment un tube fifo en C. Mon exemple de code fonctionne, mais je l’utilise avec (1) un de mes cœurs de processeur à 100% tout le temps.

Alors ma question: Existe-t-il une manière plus fluide de lire le fifo sans tuer le processeur?

#include  #include  #include  #include  #include  #include  bool suffix (char* base, char* str) { int blen = strlen(base); int slen = strlen(str); return (blen >= slen) && (0 == strcmp(base + blen - slen, str)); } bool prefix(const char *pre, const char *str) { return strncmp(pre, str, strlen(pre)) == 0; } void chomp(char *s) { while(*s && *s != '\n' && *s != '\r') s++; *s = 0; } int main(int argc, char *argv[]) { int fifo, c=0; char buf[200]; char fifo_name[] = "/var/log/proftpd_log_all.fifo"; fifo = open(fifo_name, O_RDONLY|O_NONBLOCK); while (1) { if (read(fifo, &buf, sizeof(char)*200) > 0) { if (prefix("[STOR]",buf)) { //printf("%s \n", buf); if (strstr(buf, ".jpf") != NULL) { //... } } } } printf("exit"); close(fifo); return 0; } 

    Vous avez 3 méthodes pour le manipuler: –

    1. Vous pouvez utiliser le mode Blocage lors de la lecture de la FIFO.

    2. La méthode la plus simple consiste à utiliser sleep () dans la boucle while pour suspendre le thread pendant un certain temps, ce qui réduirait momentanément la charge du processeur.

    3. Vous pouvez utiliser des signaux et des interruptions, l’enregistreur peut envoyer un signal chaque fois qu’il écrit quelque chose dans la FIFO. Le lecteur peut être suspendu jusqu’à ce qu’un signal soit reçu de l’écrivain de la FIFO et effectuer l’opération de lecture jusqu’à la fin de la FIFO, puis se suspendre.

    Dans ce cas, j’utiliserais select() pour polling. Vous pouvez le faire comme ça:

     #include  #include  #include  #include  int main() { fd_set readCheck; fd_set errCheck; char buffer[64]; struct timeval timeout; int rv; int fd = open("./fifo.test", O_RDONLY | O_RSYNC); FD_ZERO(&readCheck); FD_ZERO(&errCheck); while (1) { FD_SET(fd, &readCheck); FD_SET(fd, &errCheck); timeout.tv_sec = 1; timeout.tv_usec = 0; rv = select(fd, &readCheck, NULL, &errCheck, &timeout); if (rv < 0) { printf("Select failed\r\n"); break; } if (FD_ISSET(fd, &errCheck)) { printf("FD error\r\n"); continue; } if (FD_ISSET(fd, &readCheck)) { memset(buffer, 0, sizeof(buffer)); rv = read(fd, buffer, sizeof(buffer)); if (rv < 0) { printf("Read failed\r\n"); break; } buffer[64] = '\0'; printf(buffer); } } close(fd); return 0; } 

    Cela devrait fonctionner pour les fichiers FIFO, créés avec mkfifo() . Vous pouvez également définir un délai d'expiration infini avec NULL au lieu d'un timeout d' timeout dans l'appel de fonction.

    Cela réduira considérablement votre utilisation du processeur et vous permettra de lire uniquement des données réelles. Notez que si vous utilisez un fichier simple à la place d'une FIFO, la fonction select() attendra toujours avant de se mettre à jour, car les fichiers simples sont toujours prêts à être lus.

    Vous pouvez également lire les informations suivantes pour plus d’informations: select, pselect, poll