Comment gérer un ctrl-break du signal dans une interface de ligne de commande
Avant de commencer, je tiens à préciser que ce n'est pas un outil de ligne de commande, mais une application qui accepte les commandes par l'intermédiaire de sa propre interface de ligne de commande.
Edit: je vous dois des excuses au sujet de mon explication de avant que, apparemment, je ne voulais pas faire un très bon travail en expliquant cela. Une fois de plus...
Je suis la construction d'une interface de ligne de commande de l'application qui accepte des commandes d'un utilisateur. J'ai un gestionnaire de signal d'installation pour attraper les signaux, qui définit alors un drapeau que j'ai besoin de mettre fin à l'application. Le problème, je vais avoir toutes les fonctions de la console je peux trouver sont de blocage, ce qui signifie que je ne peut pas détecter que j'ai besoin de sortir de ma console boucle de traitement jusqu'à ce que l'utilisateur appuie sur une touche (ou entrée, selon la fonction).
Est-il un moyen standard je peux le faire soit non-bloc de la console de l'interaction, ou est-il un moyen élégant de la structure du programme, de sorte que si je viens de résilier à partir du signal de fil, que tout sera traité et libéré correctement (merci de ne pas mal comprendre, je sais comment cela pourrait être fait à l'aide de verrouillage et de libérer les ressources de la signalisation fil, mais cela peut être source de confusion, donc je préfère éviter)
Espérons que cette explication prend plus de sens...
Vous devez vous connecter pour publier un commentaire.
OK - c'est de travailler pour moi sur Windows & est portable - avis de la #ifdef SIGBREAK - ce n'est pas un signal standard.
SIGBREAK
(ctrl-break)Sur *nix, vous pouvez utiliser le
signal
fonction pour enregistrer un gestionnaire de signal:Maintenant, chaque fois que quelqu'un appuie sur Ctrl+C, votre gestionnaire de signal sera appelée.
Dans Windows: SetConsoleCtrlHandler
Sur un *nix en fonction du système que vous ne pourriez pas vraiment besoin d'un gestionnaire de signal pour que cela fonctionne. Vous pouvez spécifier que vous souhaitez ignorer le SIGINT appel
Le moyen important pour que cela fonctionne est de reconnaître que le non-blocage des fonctions n'être interrompue. Normalement, vous pourriez vous rendre compte que le blocage de la fonction a échoué (par exemple, read()) et retenter la fonction. Si c'était une autre valeur, vous permettrait de prendre les mesures appropriées erreur liée à l'action.
Une meilleure *nix solution qui est thread-safe est d'utiliser pthread_sigmask() au lieu de signal().
Par exemple, c'est comment vous signore SIGINT, SIGTERM, et le signal SIGPIPE dans le thread actuel et futur engendré de fils: