2009-06-01 3 views
2

J'ai un script qui doit commencer périodiquement des programmes sur un tableau avec les noms de programme via Perl sous Linux. Le problème est que de temps en temps l'un des programmes prend trop de temps et se bloque et doit être abandonné.L'écriture d'un programme de démarrage qui avorte programmes suspendus

Je suis actuellement le démarrage du programme en utilisant qx/$cmd/ dans un lit séparé fil à partir d'une file d'attente de démarrage partagée. Le thread principal met en file d'attente toutes les x secondes un nouvel élément dans la file d'attente. S'il y a des éléments dans la file d'attente, le thread principal tue le thread enfant et démarre un nouvel enfant.

Cela fonctionne très bien d'un point de vue fonctionnel, mais maintenant je l'ai réalisé que cela conduit à une fuite de mémoire. Comment concevez-vous un tel programme? Y at-il un module CPAN qui peut aider? S'il vous plaît laissez-moi savoir si vous avez besoin de plus de code pour comprendre le problème.

Le fil conducteur ressemble à ceci:

 if (!$startQueue->pending) { 
    $startQueue->enqueue($programList[$i++]); 
} else { 
    $log->warn("Aborting hanging execution"); 
    $starterThread->kill('KILL')->detach(); 
    $log->info("Creating new thread"); 
    $starterThread=threads->create("starterThread"); 
} 

Le fil d'enfant comme celui-ci:

sub starterThread{ 
    $SIG{'KILL'}=sub{threads->exit();}; 
    $log->info("Starter Thread started"); 
    while() { 
    my $programName=$startQueue->dequeue(); 
    $log->debug("programName:$programName"); 
    qx/$programName/; 
    } 
} 
+0

ne serait-il pas mieux de savoir pourquoi ces processus sont suspendus et le corriger? – Malfist

+0

Si vous utilisez des ressources externes/bibliothèque, alors c'est hors de votre contrôle/mains ... – weismat

+0

la plupart du temps, oui. Parfois, cela est dû à la façon dont vous l'utilisez. Si ce n'est pas le cas, votre main est obligée de prendre cette approche. – Malfist

Répondre

2

Vous pouvez jeter un oeil à Parallel::ForkManager qui vous permet de gérer un nombre fixe de processus enfants à un moment donné. Est-ce que le tableau de nom de programme reste statique pendant la durée de vie du script ou est-il mis à jour continuellement?

La fuite de mémoire semble louche; avez-vous profilé votre script et déterminé absolument que le kill/enqueue conduit à la fuite de mémoire?

+0

J'utilise Log4Perl et je peux voir à chaque thread tuer une augmentation de la taille du processus via ps et une réduction de la mémoire libre dans le système via free -m. – weismat

+0

J'ai ajouté les parties de code pertinentes au début de la discussion. – weismat

+0

Puis-je utiliser Parallel :: ForkManager dans une application multithread?Le programme sera de deux threads en tout cas de toute façon .... – weismat

0

Une alternative à un processus de gestion comme c'est un fichier PID avec un horodatage (ie contenu sont pidtimestamp), comme sendmail utilise. Ensuite, vous lancez une nouvelle copie du processus chaque minute depuis cron, ou quelque chose, et si un ancien processus est là, le nouveau processus meurt (si l'horodatage est récent) ou tue l'ancien processus (si l'horodatage est ancien) .

Je ne sais pas vraiment pourquoi votre processus de gestion doit nécessairement conduire à une fuite de mémoire, cependant. Avez-vous fermement établi que c'est le cas? Quel est ton raisonnement?

+0

Je pense que le thread kill ne fonctionne pas correctement - tuer des threads est une opération sale dans tous les cas, mais perl ne semble jamais libérer la mémoire. Je vais essayer de minimiser le problème pour un rapport de bug. – weismat

0

Normalement utilisez signal d'alarme + terrassant auto dans le programme lui-même plutôt que d'un programme de Chaser.

Questions connexes