Initier des Non-attente de Processus d'arrière-plan en Perl
J'ai un script Perl qui doit lancer un autre processus en arrière-plan et la sortie sans attendre qu'un autre script à la fin. Il y a beaucoup de discussions sur StackOverflow qui traitent de la manière de patienter en Perl ou comment ne pas attendre pour d'autres langages de programmation, mais je n'arrive pas à trouver la bonne réponse pour Perl.
J'ai lu un peu et je pensais que j'était en train de faire les bonnes choses, mais aucune de mes tentatives semblent fonctionner correctement. Voici toutes les variations que j'ai essayé jusqu'à présent en vain:
system(qq|perl /util/script.pl $id|);
system(qq|perl /util/script.pl $id &|);
exec(qq|perl /util/script.pl $id|);
exec(qq|perl /util/script.pl $id &|);
Avec chacun de ces le processus parent continue d'attendre pour l'enfant à terminer avant de quitter. S'il vous plaît laissez-moi savoir ce que je fais mal et le droit chemin à la fourchette les processus d'arrière-plan.
Merci d'avance pour votre aide!
Code complet pour faciliter le débogage. Notez que l'API->Fonction() les appels sont orientées objet, les modules de notre base de code d'usages pour les fonctions spécifiques de la base de données des interactions, etc:
sub Add {
my $self = shift;
my $domain = shift;
if(!$self->IsValid($domain)) { return; }
my $SQL = qq| insert into domains set added=NOW(),domain=| . API->Database->Quote($domain);
my $sth = API->DatabaseQuery($SQL);
$SQL = qq| select last_insert_id() |;
$sth = API->DatabaseQuery($SQL);
my $id = $sth->fetchrow_array();
my $command = qq|perl /home/siteuser/util/new.pl $id &|;
system($command);
return {'id'=>$id,'domain'=>$domain};
}
Vous allez accepter toute réponse ici?
OriginalL'auteur Russell C. | 2010-12-13
Vous devez vous connecter pour publier un commentaire.
Le premier est conçu pour fonctionner de cette façon -
system
exécute la commande et des finitions de la fin.Les deux derniers sont également conçues de cette manière -
exec
est spécifiquement conçu pour ne jamais revenir. Essentiellement, il remplace le processus parent avec le processus de l'enfant.Cependant, celle-ci devrait faire l'affaire: la commande lancée à partir de la
system
appel shell, qui est votre chaîne à exécuter. Depuis que la chaîne se termine par "&", cela signifie que l'environnement de ligne de commande de lancement de votre commande en tant que processus d'arrière-plan, et la finition de sa propre exécution après que le lancement.Pouvez-vous s'il vous plaît poster plus de code illustrant comment #2 n'a pas fonctionné?
Aussi, voir ce qui se passe si vous essayez de backticks ou qx:
Aussi, comme un moyen de réduire les incertitudes, pouvez-vous s'il vous plaît exécuter la suite et dites-moi ce qui s'imprime:
Je ne pense pas que votre exemple sera de retour aucune sortie utile.
Je pensais que le deuxième était correct, mais le script est certainement en attente sur le processus de l'enfant à la fin. Si je commente le système() de la ligne du script parent quitte presque immédiatement, et avec cette ligne, il faut 3 à 4 secondes pour quitter ce qui est combien de temps l'enfant prend à exécuter. J'ai essayé qx et j'ai aussi essayé backticks mais ni le fini de l'exécution de l'enfant à tous. Je ne suis pas sûr de ce que je peux fournir pour faciliter le dépannage. Des idées?
vous êtes correct. Le qx|| exemple ne retourne rien.
Kane - il est destiné à retourner l'habitude shell sortie d'arrière-plan (par exemple, le PID de backgrounded processs). Elle pourrait avoir besoin de redirection de STDERR - pas de xtterm en face de moi en ce moment donc je ne me souviens pas si "&" sortie vers stdout.
OriginalL'auteur DVK
Faites-vous appel à
fork()
avant d'appelersystem
ouexec
?Ils sont tous les deux à peu près équivalent.
Les deux sont toujours provoque le parent d'attendre. Toutes les idées sur la façon de modifier, de sorte que le parent ne veut pas attendre?
La bonne façon est d'utiliser
fork()
pour créer un processus d'arrière-plan, puis lancersystem
ouexec
à partir de ce processus d'arrière-plan.(Puisque c'est du Perl, j'aurais du commencer ce dernier commentaire avec "Une bonne manière de ...")
OriginalL'auteur mob
Vous avez besoin de dissocier l'enfant de la mère.
Voir perldoc -q démon. Ou Proc::Daemon
C. - vous n'avez pas besoin de courir comme un "pour toujours" démon - tout simplement commencer comme une seule, de faire leur travail et de sortie. Il n'y a absolument rien de ce qui est techniquement exigeant que le démon s'exécute jamais. +1
OriginalL'auteur runrig
L'aide d'une fourchette est un bon moyen de processus d'arrière-plan:
Ce qui est étrange. Êtes-vous sûr de mettre l'instruction exit à l'intérieur de l'enfant de bloc?
Je l'ai fait. Le tout est très étrange en effet. C'est pourquoi j'ai posté ici. D'autres idées de ce qui pourrait se passer?
Je vous suggère de remplacer /util/script.pl avec un programme simple comme: for (1 .. 10) { print "sleeping $_ ...\n"; sleep 1 } Ce qui peut vous aider à déboguer le problème.
OriginalL'auteur Naveed