10
votes

Comment démarrer un processus dans son propre groupe de processus?

Je voudrais démarrer un processus dans son propre groupe de processus (ou, en variante, modifier son groupe une fois démarré) et:

  • Demandez aux processus du groupe de répondre à Ctrl + C du terminal
  • Obtenez l'ID du groupe de processus afin que je puisse mettre fin à tous les processus du groupe via la commande kill .

    Remarque: j'ai essayé setsid prog [args] mais les processus ne répondent pas à CTRL + C du terminal ni je pourrais obtenir le nouvel identifiant de groupe de processus.

    J'ai également essayé de modifier le groupe de processus via le fichier setpgrp ($ pid, $ pid) et posix :: sepgid ($ pid, pid $ pid) , sans disponible.

    EDIT: Le problème plus vaste:

    J'ai un processus (un seul fileté; appelons-le le processus "PROLICIF" P ) qui commence de nombreux processus d'enfants de manière synchrone (l'une après l'autre; il commence une nouvelle lorsque le processus d'enfant précédent terminer). Depuis le terminal, je veux pouvoir tuer P et l'arborescence des processus en dessous. Pour ce faire, je pourrais simplement organiser les processus dans le groupe p . Cependant, le comportement par défaut est que p est dans le groupe de son processus parent. Cela signifie que le parent p sera tué si je tue tous les processus dans le groupe P S, sauf si j'ai p et son arbre être dans leur propre groupe.

    Mon intention est de tuer p et de l'arborescence en dessous, mais pas P s parent. En outre, je ne peux pas modifier p s lui-même.


4 commentaires

Veuillez clarifier la différence entre le comportement par défaut du lancement de processus (comme observé par Ninjalj ci-dessous), avez-vous besoin d'accomplir?


J'espère que la modification que j'ai ajoutée ci-dessus (le problème plus large) aide à clarifier l'intention.


Vous pouvez Fork et SETPGRP pour avoir le processus sur un nouveau groupe de processus. Ensuite, au lieu de P et de ses enfants, vous aurez des enfants PP, PC et PC. Puisque vous SETPGRP 'D PC après Fourchette , il figurera sur son propre groupe de processus, de sorte que vous pouvez le tuer et ses enfants en une fois. Avoir PP ATTENDRE , et cela attendra la mort de PC puis la sortie (ou tout ce que vous voulez que ce soit).


C'est précisément ce qui était requis. Merci!! Un seul morceau du puzzle est laissé à mettre en place. Je veux que mon script parent perl se termine avec un statut d'erreur indiquant qu'il a été interrompu. S'il vous plaît voir mon message sur la section Réponses ci-dessous.


3 Réponses :


1
votes

EDIT: Si ce que vous vouliez faire était d'utiliser setsID mais trouvez l'ID de session et / ou le PID du processus résultant:

Si vous lancez un processus via la commande setsid, il ne sera pas joint à votre terminal, Donc, bien sûr, il ne répondra pas à Ctrl-C.

Vous pouvez le trouver en grepping à travers la sortie de xxx

ou quelque chose de plus limité comme xxx p> ou une simple langue simple via proc / [pid] / stat pour toutes les entrées et en regardant l'identifiant de la session et quoi que ce soit d'intérêt (voir l'homme Proc pour plus de détails)

La page de l'homme de SetSID ne donne pas Tous les indicateurs pour générer directement une sortie, mais vous pouvez faire de manière triviale votre propre version qui imprime les informations souhaitées, en modifiant la norme.

Par exemple, saisissez une copie de setsID.c de l'un des résultats pour

http://www.google.com/codeSearch?as_q=setsid&as_package=util-linux

commentaire La NLS comprend, les trucs locaux et la macro d'erreur _ ("") qui causera des problèmes, puis ajoutez ce droit avant la ligne ExecVP: xxx


1 commentaires

Ce que j'aurais dû dire était "Certaines macro non disponibles dans une version à une seule version utilisée pour afficher un message d'erreur"



5
votes

Que voulez-vous dire "Démarrer un processus dans son propre groupe de processus"? La coquille lance des processus dans leurs propres groupes de processus, c'est ainsi que le contrôle des travaux (en disposant d'un groupe de processus pour les processus au premier plan et plusieurs groupes de processus pour chaque pipeline lancé à l'arrière-plan).

Pour voir que la coque se lance Un nouveau groupe de processus pour chaque pipeline, vous pouvez le faire: p> xxx pré>

qui montrera quelque chose comme: p>

setpgrp;
system("ps fax -o pid,pgid,cmd");


6 commentaires

Point intéressant ... Quelle est l'intention? Propre groupe de processus ou propre identifiant de session? Je suppose un peu le plus tard, mais nous devrons attendre que l'affiche clarifie


@Chris: Je pense que l'op utilisé setsid car il n'y a pas d'utilitaire SETPGRP .


@ninjalj: Cela pourrait être ça. Je me demande quelle était l'intention. Quoi qu'il en soit, j'ai appris certaines choses tout en mettant ensemble ma réponse peut-être non pertinente ;-)


@Chris: Votre réponse est pertinente. J'ajoutais juste un angle différent.


@ninjalj: Vous avez raison sur l'argent avec la pensée de Perl. Le processus "profilique" que je vous réfère ci-dessus est un processus de PERL qui appelle le système à plusieurs reprises plusieurs fois. Lorsque son processus d'enfant actuel est résilié, P crée un autre processus d'enfant, inconscient du fait que l'enfant précédent a été interrompu. Mon objectif est d'organiser P et l'arbre de processus ci-dessous à être tué lorsqu'il est interrompu à partir du terminal, mais PAS parent de P


@Beluchin: Comme je l'ai dit, vous pouvez Fork et SETPGRP sur l'enfant. Ensuite, vous pouvez tuer le groupe de processus de l'enfant du parent.



1
votes

Voici la réponse dans le code PERL suivant les suggestions de Ninjalj ci-dessus:

prolific_wrapper.pl xxx

Merci encore!


5 commentaires

Vous pouvez toujours KILLE INT => $$ au lieu de EXIT , bien que je ne sois pas sûr qu'il sera aussi propre pour sortir de cette façon.


Otoh perl -e 'Kill int => $$;'; echo $? montre 130 dans ma boîte. Donc, pour moi, ce serait sortie 130


Quoi qu'il en soit, je ne suis pas sûr que vous devez attraper SIGINT, ^ c devrait l'envoyer à l'ensemble du groupe de processus, le processus de votre enfant Perl l'ignore, mais il obtiendrait le code de sortie du système System .


Comme on peut le voir par perl -e 'sortie system "sommeil 5"'; echo $? et ^ c


1. Je dois piéger SIGINT dans le wrapper (le parent) parce que je dois tuer les processus du groupe dirigé par Prolifique. 2. J'utiliserais la sortie 130. Je ne suis pas sûr de l'effet de Kill int => $$ sera dans un gestionnaire de signal.