2009-06-01 6 views
2

Ich habe ein Skript, das regelmäßig Programme aus einem Array mit Programmnamen über Perl unter Linux starten muss. Das Problem ist, dass von Zeit zu Zeit eines der Programme zu lange dauert/hängt und abgebrochen werden muss.Schreiben eines Startprogramms, das hängende Programme abbricht

Derzeit starte ich das Programm mit qx/$cmd/ in einem separaten Thread, der aus einer freigegebenen Startwarteschlange liest. Der Haupt-Thread reiht alle x Sekunden ein neues Element in die Warteschlange ein. Wenn sich Elemente in der Warteschlange befinden, wird der untergeordnete Thread vom Hauptthread beendet und ein neues untergeordnetes Objekt wird gestartet.

Dies funktioniert aus funktionaler Sicht gut, aber jetzt habe ich erkannt, dass dies zu einem Speicherverlust führt. Wie würdest du ein solches Programm gestalten? Gibt es ein CPAN-Modul, das helfen kann? Bitte lassen Sie mich wissen, wenn Sie weiteren Code benötigen, um das Problem zu verstehen.

Der Haupt-Thread sieht wie folgt aus:

 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"); 
} 

Das Kind Thread wie folgt aus:

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

Wäre es nicht besser, herauszufinden, warum diese Prozesse hängen und korrigieren? – Malfist

+0

Wenn Sie externe Ressourcen/Bibliothek verwenden, ist es außerhalb Ihrer Kontrolle/Hände ... – weismat

+0

die meiste Zeit, ja. Manchmal liegt es an der Art, wie Sie es benutzen. Wenn das nicht der Fall ist, ist Ihre Hand gezwungen, diesen Ansatz zu wählen. – Malfist

Antwort

2

Sie können sich Parallel::ForkManager ansehen, mit der Sie eine feste Anzahl untergeordneter Prozesse zu einem bestimmten Zeitpunkt verwalten können. Bleibt das Array des Programmnamens während der Lebensdauer des Skripts statisch oder aktualisiert es sich ständig?

Das Speicherleck klingt fischig; Hast du dein Script profiliert und festgestellt, dass das Kill/Enqueue zu dem Speicherleck führt?

+0

Ich benutze Log4Perl und ich kann mit jedem thread kill eine Vergrößerung des Prozesses über ps und eine Reduzierung des freien Speichers im System über free -m erkennen. – weismat

+0

Ich habe die relevanten Codeteile zum Beginn der Diskussion hinzugefügt. – weismat

+0

Kann ich den Parallel :: ForkManager in einer Multithread-Anwendung verwenden?Das Programm wird auf jeden Fall sowieso zwei Threads sein .... – weismat

0

Eine Alternative zu einem Manager-Prozess wie das ist ein PID-Datei mit einem Zeitstempel (dh Inhalt pidtimestamp), wie sendmail verwendet. Dann startet man jede Minute eine neue Kopie des Prozesses von cron oder etwas, und wenn ein alter Prozess da ist, stirbt der neue Prozess entweder ab (wenn der Zeitstempel neu ist) oder tötet den alten Prozess (wenn der Zeitstempel alt ist) .

Ich weiß eigentlich nicht, warum Ihr Manager-Prozess notwendigerweise zu einem Speicherverlust führen sollte. Haben Sie fest festgestellt, dass dies der Fall ist? Was ist deine Argumentation?

+0

Ich denke, dass der Thread-Kill nicht richtig funktioniert - das Töten von Threads ist in jedem Fall ein schmutziger Vorgang, aber Perl scheint niemals den Speicher freizugeben. Ich werde versuchen, das Problem für einen Fehlerbericht zu minimieren. – weismat

0

Normalerweise verwenden ALARM-Signal + Selbstmord innerhalb des Programms selbst, anstatt ein Chaser-Programm.

Verwandte Themen