Comment tuer un processus d'arbre par programme sur Linux à l'aide de C
Je suis en train d'écrire une fonction qui génère un processus enfant, permet de l'exécuter pour un certain laps de temps et puis la tue si elle n'a pas fini d':
int sysExecTimeout(const char * exePath, int timeoutSec);
Dans la fonction, j'utilise fork
et execl
à pondre l'enfant, et, quand il expire, j'utilise kill(pid, SIGTERM)
et kill(pid, SIGKILL)
après 2 secondes, pour s'assurer du décès de l'enfant:
pid_t pid = fork();
if(pid == 0) {
execl("/bin/sh", "sh", "-c", exePath);
exit(127);
} else if(pid != -1) {
//timeout code
if(timeout) {
kill(pid, SIGTERM);
sleep(2);
kill(pid, SIGKILL);
}
}
Je suis sous Linux, et il semble que lorsqu'un parent meurt, l'enfant n'est pas tué automatiquement. Donc, les deux kill
appels il suffit de tuer le /bin/sh
processus et de laisser le exePath
commande en cours d'exécution, car il est un processus enfant de /bin/sh
.
Je suis en train d'écrire le sysExecTimeout
fonction telle qu'il tue tout le processus arbre enraciné au pid
, où pid
est le PID de pid = fork()
J'ai besoin de cette parce que le exePath
commande va lancer d'autres commandes, qui peuvent également engendrer d'autres commandes, ce qui pourrait se coincer et de consommer les ressources.
Je n'ai pas de contrôle sur le exePath
fichiers binaires et des scripts que exécutée, donc je ne peux pas écrire mon propre parent-meurt-si-tuer-les-enfants logique.
J'ai essayé d'utiliser kill(0, SIGTERM)
, qui a presque fait le travail, sauf qu'il a aussi tué mon propre processus 🙂
Je me demande si il y a un drapeau je peux l'activer par programmation en C qui dit "hey man, quand je mourrai, tous mes enfants et de les tuer, et de répéter de manière récursive pour leurs enfants" ce qui fait que l'ensemble du processus de l'arbre a commencé à partir de ce programme meurt (en supposant que le PID/PPID de la chaîne peut être suivie).
Je pouvais le drapeau ici:
if(pid == 0) {
turnOnRecursiveDeathFlag();
system(exePath);
//execl("/bin/sh", "sh", "-c", exePath);
exit(127);
}
Est-il un moyen de le faire? J'ai cherché pendant un certain temps, mais tout ce que je peux trouver sont des hacks à l'aide de ps -ef
, ou de modifier les processus enfants que vous êtes en cours d'exécution, etc.
} else if(pid == -1) {
: cela indique un problème avec fork()
, pas le processus de l'enfant..Oui, désolé, c'est une faute de frappe 🙂
OriginalL'auteur Alin Tomescu | 2013-03-28
Vous devez vous connecter pour publier un commentaire.
Utilisation setpgid à l'enfant de mettre ses GPID égal à son propre PID. Le parent peut alors tuer(-pid,...) pour le signal de l'ensemble du groupe.
Cela devrait le faire.
Une chose de plus, lorsque vous frayer un shell, assurez-vous de ne pas permettre le contrôle du travail. Sinon, il permettra de créer ses propres groupes de processus. Votre "/bin/sh-c" est bien.
Btw, puisque je ne peux pas éditer vos post, vous devriez changer setgpid à setpgid, ce qui semble être le nom correct.
J'ai corrigé pour lui @AlinTomescu... ou je suppose que son cours de révision
OriginalL'auteur DoxyLover