2009-12-29 4 views
1

Dans mon application Web Perl/CGI, j'ai parfois besoin d'exécuter un long processus qui rend l'attente de la page suivante interminable. J'ai donc désactivé le tampon comme ci-dessous afin que le contenu de la page soit envoyé avant que le long processus ne s'exécute.Dois-je désactiver le tampon pour lancer un processus d'arrière-plan dans un programme CGI?

local $| = 1; 
print "Content-type: text/html\n\n"; 
print $output; 
&background_process(); 

Cependant, il me semble que le tampon a ses utilisations et je ne serais pas l'habitude de le faire. Existe-t-il un meilleur moyen d'exécuter un long processus et de renvoyer html au client rapidement? Est-ce que je devrais forking ou somesuch?

Répondre

4

Voici un code que j'utilise pour frayer déclencher un processus d'arrière-plan dans mon script FastCGI:

$SIG{CHLD} = 'IGNORE'; 

# This should flush stdout. 
my $ofh = select(STDOUT);$| = 1;select $ofh; 

my $kpid = fork; 
if ($kpid) 
{ 
    # Parent process 
    waitpid($kpid, 0); 
} 
else 
{ 
    close STDIN; 
    close STDOUT; 
    close STDERR; 
    setsid(); 
    my $gpid = fork; 
    if (!$gpid) 
    { 
     open(STDIN, "</dev/null") ; 
     open(STDOUT, ">/dev/null") ; 
     open(STDERR, ">/dev/null") ; 
     # Child process 
     exec($pgm, @execargs) ; 
    } 
    exit 0; 
} 

Quelques points saillants ici:

  • J'ignore SIGCHLD, qui est le signal vous obtenez lorsque votre enfant traite sorties.
  • Je vide STDOUT, donc le navigateur Web obtient la page entière.
  • Je double deux fois pour m'assurer que le serveur Web sera capable de quitter même si le processus que j'essaie de lancer est toujours en cours d'exécution.
  • Je redirige tous les descripteurs de fichier standard pour m'assurer que le processus petit-enfant est complètement détaché du parent.
+1

J'ai utilisé exactement le même code dans mon script. Cependant, le script cgi ne répond pas immédiatement au client. Il envoie seulement la réponse après que l'enfant se termine même si je fourche deux fois. Toute suggestion où regarder? – Wilderness

4

Le meilleur moyen est de fourcher votre processus et de le mettre en arrière-plan. De cette façon, il ne sera pas arrêté par l'utilisateur qui quitte la page, et la page ne sera pas en état de chargement dans le navigateur Web tout le temps.

+0

J'ai un problème similaire avec un script perl-cgi. Comment capturer un message d'erreur à partir de ce processus en arrière-plan? – Wilderness

Questions connexes