OVH Cloud OVH Cloud

IPC

3 réponses
Avatar
Paul Bert
Bonjour,


Je souhaite lancer l'exécution d'un programme au travers d'un script
perl, et que mon script reprenne la main soit parce que le processus
fils est terminé, soit après un temps donné (timeout).


my $pid = fork();
if ($pid == 0) #son
{

my @cmd = (@args, ">$output2>&1");
exec(@cmd) or die "...";
}
elsif ($pid > 0) # father
{
#attendre la fin du process ou un timeout
}
else #error
{
die "...";
}


Toufois, je recontre plusieurs problèmes :

1. Attendre la fin ou le timeout : je ne sais pas comment faire :(

2. Dans mon exec(), je souhaite rediriger la sortie de ma commande dans
un fichier (le ">$output>2>&1") ... mais le fichier n'est pas créé et
je ne comprends pas pourquoi :(

3. au bout du timeout, si le programme n'est pas terminé, je veux le
killer depuis le père. Ca, ca va parce que j'ai son PID. Cependant, il
se peut que le programme que je lance soit crée aussi des fils, soit
fasse lui aussi un fork()+exec().
Comment garder la trace de tous ces processus "enfants" et tous les
killer ?


Merci de votre aide,

P. Bert

3 réponses

Avatar
dominix
Paul Bert wrote:
Bonjour,


Je souhaite lancer l'exécution d'un programme au travers d'un script
perl, et que mon script reprenne la main soit parce que le processus
fils est terminé, soit après un temps donné (timeout).


my $pid = fork();
if ($pid == 0) #son
{

my @cmd = (@args, ">$output2>&1");
exec(@cmd) or die "...";
}
elsif ($pid > 0) # father
{
#attendre la fin du process ou un timeout
}
else #error
{
die "...";
}


Toufois, je recontre plusieurs problèmes :

1. Attendre la fin ou le timeout : je ne sais pas comment faire :(



wait ?
il y a aussi les signaux
$SIG{ALRM} = sub { die "timeout" };


2. Dans mon exec(), je souhaite rediriger la sortie de ma commande
dans un fichier (le ">$output>2>&1") ... mais le fichier n'est pas
créé et je ne comprends pas pourquoi :(



">$output 2>&1"
^ espace ici {attention}


3. au bout du timeout, si le programme n'est pas terminé, je veux le
killer depuis le père. Ca, ca va parce que j'ai son PID. Cependant, il
se peut que le programme que je lance soit crée aussi des fils, soit
fasse lui aussi un fork()+exec().
Comment garder la trace de tous ces processus "enfants" et tous les
killer ?



reboot ? :P
non je blague,
il y a kill ,mais il te faut les ProcessID


Merci de votre aide,

P. Bert


simple suggestion, avant que Paul ne reponde ;-)
va, cours, vole pour voir l'excelent
http://www.enstimac.fr/Perl/DocFr/perlipc.html


--
dominix

Avatar
dominix
dominix" <dominix"at wrote:
Paul Bert wrote:
Bonjour,

...



simple suggestion, avant que Paul ne reponde ;-)
oops, Paul _Gaborit_ je veux dire (grand contribruiteur

de ce NG et mainteneur de la doc de Perl en Francais
si apres cit'e

va, cours, vole pour voir l'excelent
http://www.enstimac.fr/Perl/DocFr/perlipc.html



Avatar
Paul GABORIT
À (at) 17 Nov 2003 08:55:21 GMT,
Paul Bert écrivait (wrote):
[...]
my @cmd = (@args, ">$output2>&1");
exec(@cmd) or die "...";
[...]

2. Dans mon exec(), je souhaite rediriger la sortie de ma commande dans
un fichier (le ">$output>2>&1") ... mais le fichier n'est pas créé et
je ne comprends pas pourquoi :(


...juste sur ce point particulier.

Si vous faites un 'exec' avec une liste d'arguments, vous ne passez pas par un
shell. C'est un gain de vitesse (un seul processus au lieu de deux) et de
sécurité (vous maitrisez totalement l'interprétation des différents arguments:
pas de d'échappement à gérer).

En revanche, vous ne pouvez plus utiliser les redirections d'entrée/sortie du
shell !

Deux solutions :

La plus simple : repasser par un appel via le shell.

La plus sûre : faire la reditection vous-même. Il faut savoir que les
FileHandle sont hérités à travers un 'fork' et un 'exec'. Donc, il vous suffit
de réouvrir STDOUT vers votre fichier avant l'appel à 'exec' pour faire votre
propre redirection.

--
Paul Gaborit - <http://www.enstimac.fr/~gaborit/>
Perl en français - <http://www.enstimac.fr/Perl/>