2015-04-18 1 views
0

J'ouvre une coquille comme celui-ci dans mon code C++:Comment fermer shell précédemment ouvert (C++)

int pid = fork() 
if (pid==0){ 
    system("script.sh") 
} 
[rest of the code] 

A la fin de mon programme C++, je veux aussi fermer cette coquille ouverte, est que possible?

+0

'[reste du code]' ne fonctionnera pas jusqu'à ce que le système '() 'renvoie, ce qui n'arrivera que lorsque le shell sera fermé. –

+0

En fait, il fonctionne en raison de l'utilisation de 'fork()'. – NullX4

+0

Dans le processus d'origine, oui. ... Mais vous vous rendez compte que cela va courir aussi chez l'enfant quand la coquille sortira, n'est-ce pas? –

Répondre

0

Lorsque script.sh est terminé, la coquille, il a été exécuté en mettra fin à lui-même, vous n'avez pas besoin de « fermer » il.

Cependant, si le processus parent est toujours en cours d'exécution, l'enfant deviendra un « zombie » (marqué avec un Z dans la sortie de la commande ps). Il restera dans cet état jusqu'à ce que le parent lise son code de retour ou se termine.

Donc, si [reste du code] est bref, vous ne pouvez pas avoir à faire quoi que ce soit. Lorsque le parent quitte, l'enfant sera nettoyé par le système d'exploitation.

Mais si [reste du code] fonctionne pendant un certain temps, ou ce segment de code est appelé plusieurs fois, alors vous voulez nettoyer vos zombies afin qu'ils ne s'accumulent pas. Ceci est fait avec l'appel système waitpid().

Par exemple:

int pid = fork() 
if (pid==0){ 
    system("script.sh") 
} else { 
    int status = 0; 
    int result = waitpid(pid, &status, 0); 
    if (result == -1) { 
     /* error */ 
    else { 
     [rest of the code] 
    } 
} 

Notez que le processus parent va bloquer dans l'appel waitpid() jusqu'à ce que l'enfant ait fini. Si ce n'est pas ce que vous voulez, vous pouvez passer l'option WNOHANG à la place de 0 comme dernier argument. Quand il reviendra, 'status' contiendra le code retour de votre script. Vous pouvez obtenir plus de détails à ce sujet en lisant "man 2 waitpid".

Mise à jour (en réponse au commentaire de ce script ne se termine pas sur lui-même):

La solution la plus propre dans l'abstrait serait probablement de remanier de sorte que le script ne sortie sur son propre, mais si pour Quelle que soit la raison qui ne soit pas possible, le parent peut tuer le script de force en utilisant l'appel système kill(). Le code ressemblerait à quelque chose comme ceci:

#include <sys/types.h> 
#include <signal.h> 

int pid = fork() 
if (pid==0){ 
    system("script.sh") 
} else if (pid > 0) { 
    /* do whatever in parent*/ 

    /* Note it is very important to check that fork did not fail */ 
    /* and return -1, because if you do "kill(-1, SIGTERM)" you */ 
    /* are in fact sending the TERM signal to **every process** */ 
    /* on your system. If running as root, this would be A Very Bad */ 
    /* Thing. */ 
    kill(pid, SIGTERM); 
} else { 
    /* error */ 
} 

kill() peut retourner -1 en cas d'erreur, donc si vous vous souciez beaucoup sur le script ne pas être nettoyé, vous pouvez vérifier. Si, par exemple SIGTERM ne tue pas, vous pouvez grimper à envoyer SIGKILL (comme « kill -9 » de la ligne de commande):

if (kill(pid, SIGTERM) == -1) { 
    kill(pid, SIGKILL); 
} 
+0

La chose est script.sh ne termine jamais. Je veux donc le "forcer" à se fermer juste avant la fin du processus parent. – NullX4

+0

Notez que vous disposez de trois générations de processus ici, script.sh fonctionne chez l'enfant, alors que votre programme original est le grand-parent. Celui créé par fork() est le parent entre les deux. Faites comme suggéré et utilisez fork/exec, pas fork/system, car cela réduira cela à un seul niveau. À partir du processus parent, vous pouvez ensuite envoyer un signal pour terminer l'enfant. –