GNU/Linux >> Tutoriels Linux >  >> Linux

Comment un programme C peut-il interroger l'entrée de l'utilisateur tout en effectuant simultanément d'autres actions dans un environnement Linux ?

Votre tâche nécessite une boucle d'événement basée sur select ou epoll . Un événement qu'il attendrait est l'entrée de l'utilisateur - lorsque STDIN_FILENO devient prêt à être lu. Un autre est le minuteur périodique de 1 seconde lorsque vous devez interroger le contrôleur.

Il existe de nombreuses bibliothèques qui implémentent une boucle d'événements pour vous afin que vous puissiez vous concentrer sur les événements que vous devez gérer et comment. libevent est l'un des plus anciens, riche en fonctionnalités et populaire.


Je crois que la méthode "Unix" ne consisterait pas à demander une entrée utilisateur, mais à réagir à un signal utilisateur. Par exemple, lorsque l'utilisateur appuie sur Ctrl-C, le processus en cours d'exécution reçoit SIGINT.

Un exemple d'utilisation correcte de SIGINT pour interrompre une boucle peut être trouvé ici. Copiez-le dans la réponse au cas où le lien deviendrait obsolète :

#include <stdlib.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

static volatile sig_atomic_t got_signal = 0;

static void my_sig_handler(int signo)
{
    got_signal = 1;
}

int main()
{
    struct sigaction sa;

    memset(&sa, 0, sizeof(struct sigaction));
    sa.sa_handler = &my_sig_handler;
    if (sigaction(SIGINT, &sa, NULL) == -1) {
        perror("sigaction");
        return EXIT_FAILURE;
    }

    for (;;) {
        if (got_signal) {
            got_signal = 0;
            printf("Received interrupt signal!\n");
        }
        printf("Doing useful stuff...\n");
        sleep(1); /* Sleep is not only useful, it is essential! */
    }
    return EXIT_SUCCESS;
}

(dans votre cas ce serait une bonne idée de mettre break; dans le if bloquer ou utiliser while(!got_signal) )


La réponse simple est le multi-threading, où vous avez un thread déployé pour attendre l'entrée de l'utilisateur, tandis que la boucle continue. Alors ayez ceci :

char flag = 1;

while (flag) {
     // run the loop

     // if thing happens deploy the thread which will ask user for input

}

Je n'ai pas fait de threading depuis un moment, je pense que cette page serait mieux que moi en essayant de vous l'expliquer :https://randu.org/tutorials/threads/


Linux
  1. Comment puis-je modifier le $PATH sous Linux ?

  2. Comment puis-je modifier le groupe par défaut d'un utilisateur sous Linux ?

  3. Comment puis-je rechercher un nom d'utilisateur par identifiant sous Linux?

  4. Comment puis-je simuler la quantité de RAM installée pour un programme spécifique sous Linux ?

  5. Comment puis-je créer un utilisateur uniquement pour sftp ?

Comment activer le sudo sans mot de passe pour l'utilisateur sous Linux

Comment changer d'utilisateur sous Linux

Comment désactiver la connexion SSH pour l'utilisateur root sous Linux ?

Comment puis-je générer une couverture de code pour les packages Swift sous Linux ou OS X ?

Comment puis-je attribuer un mot de passe initial/par défaut à un utilisateur sous Linux ?

Linux - Comment puis-je voir ce qui attend les E/S de disque