![]() |
|
|||||||
| Newsgroup de.comp.lang.perl.cgi CGI-Programme in der Programmiersprache Perl. |
![]() |
|
|
Themen-Optionen | Ansicht |
|
#1
|
|||
|
|||
|
Hallo,
ich habe ein kleines Perl script geschrieben, dass eine externe Anwendung startet, welches wiederrum je nach Übergabeparameter allerlei Dinge nach stdout zeilenweise Ausgeben kann (z.B. die Zahl Pi berechnet) und in vielen Fällen niemals oder nach sehr langer Zeit endet: open(PROGRAMM, "/usr/bin/programm -a $uebergabeparameter |") || die "Problem mit Programm aufgetreten: $!"; while (<PROGRAMM>) { print "$_<BR>"; } close (PROGRAMM) || die "Kann Programm nicht beenden: $!"; Im Browser werden die Ausgaben zeilenweise angezeigt. Soweit so gut. Nur wenn ich den Browser schließe, bzw. den Stop-Button des Browsers klicke, so läuft der PROGRAMM-Prozess im Hintergrund weiter. Kann man das Perl-Script irgendwie so anpassen, dass bei Abbruch der http-Verbindung auch der externe Prozess gekillt wird? TIA, Dominik |
|
|
||||
|
||||
|
|
|
#2
|
|||
|
|||
|
Dominik Pusch wrote:
> > ich habe ein kleines Perl script geschrieben, dass eine externe > Anwendung startet, welches wiederrum je nach Übergabeparameter > allerlei Dinge nach stdout zeilenweise Ausgeben kann (z.B. die Zahl Pi > berechnet) und in vielen Fällen niemals oder nach sehr langer Zeit > endet: > > open(PROGRAMM, "/usr/bin/programm -a $uebergabeparameter |") || > die "Problem mit Programm aufgetreten: $!"; > > while (<PROGRAMM>) > > { > print "$_<BR>"; > } > close (PROGRAMM) || die "Kann Programm nicht beenden: $!"; > > > Im Browser werden die Ausgaben zeilenweise angezeigt. Soweit so gut. > Nur wenn ich den Browser schließe, bzw. den Stop-Button des Browsers > klicke, so läuft der PROGRAMM-Prozess im Hintergrund weiter. > Kann man das Perl-Script irgendwie so anpassen, dass bei Abbruch der > http-Verbindung auch der externe Prozess gekillt wird? Der PROGRAMM-Prozess läuft so lange weiter bis er fertig ist oder er nichts mehr auf die Pipe schreiben kann, weil sein Parent weg ist, oder sein Parent ihn killt. Der Parent muss das also steuern, indem er prüft, ob die Browserverbindung noch da ist. Grüße Frank -- Dipl.-Inform. Frank Seitz Anwendungen für Ihr Internet und Intranet Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel Homepage: http://www.fseitz.de/ XING-Profil: http://www.xing.com/profile/Frank_Seitz2 |
|
#3
|
|||
|
|||
|
Frank Seitz wrote:
>> ich habe ein kleines Perl script geschrieben, dass eine externe >> Anwendung startet [..] >> open(PROGRAMM, "/usr/bin/programm -a $uebergabeparameter |") || >> die "Problem mit Programm aufgetreten: $!"; >> >> while (<PROGRAMM>) >> >> { >> print "$_<BR>"; >> } >> close (PROGRAMM) || die "Kann Programm nicht beenden: $!"; [..] >> Nur wenn ich den Browser schließe, bzw. den Stop-Button des >> Browsers klicke, so läuft der PROGRAMM-Prozess im Hintergrund >> weiter. Kann man das Perl-Script irgendwie so anpassen, dass bei >> Abbruch der http-Verbindung auch der externe Prozess gekillt wird? > > Der PROGRAMM-Prozess läuft so lange weiter bis er fertig ist > oder er nichts mehr auf die Pipe schreiben kann, weil sein Parent > weg ist, oder sein Parent ihn killt. > > Der Parent muss das also steuern, indem er prüft, ob die > Browserverbindung noch da ist. Also ich habe die Prozesse mal verfolgt: `-apache2---script.pl---programm Wenn ich jetzt den Browser stoppe, dann erbt init den Prozess programm. apache2 scheint also script.pl zu killen, was die Child- Prozesse von script.pl verwaisen lässt. Laut meine Infos, sollte aber jedem verwaisten Prozess immer (von init?) ein SIGHUP gesendet werden? Aber auch das passiert nicht! Wenn ich meinem verwaisten Programm manuell ein SIGHUP sende, terminiert es nämlich auch! Aber zurück zu Deiner Ausage: Der parent von meinem script.pl ist ja apache. Dieser terminiert script.pl ja auch ordnungsgemäß, wenn die Browserverbindung abreißt. Nur script.pl terminiert dabei nicht programm! Aber zurück zur Ausgangsfrage: Kann man ein cgi-Perlscript irgendwo so gestalten (eine zusätzlich Anweisung oder ähnliches?), dass wenn es ein entsprechende KILL-Signal von apache bekommt, auch ein kill-Signal an seine Kinder weiterleitet, bevor es sich entgültig terminiert? Vielen Dank für die Antwort, Dominik |
|
#4
|
|||
|
|||
|
Dominik Pusch wrote:
> Frank Seitz wrote: >> >> Der PROGRAMM-Prozess läuft so lange weiter bis er fertig ist >> oder er nichts mehr auf die Pipe schreiben kann, weil sein Parent >> weg ist, oder sein Parent ihn killt. >> >> Der Parent muss das also steuern, indem er prüft, ob die >> Browserverbindung noch da ist. > > Also ich habe die Prozesse mal verfolgt: > `-apache2---script.pl---programm > > Wenn ich jetzt den Browser stoppe, dann erbt init den Prozess > programm. apache2 scheint also script.pl zu killen, was die Child- > Prozesse von script.pl verwaisen lässt. Da stimmt was nicht. Meines wissens killt apache seine childs nicht. > Laut meine Infos, sollte aber jedem verwaisten Prozess immer (von > init?) ein SIGHUP gesendet werden? Das stimmt definitiv nicht. Der parent wird unterrichtet (SIGCHLD), wenn sein child stirbt, aber nicht umgekehrt. Das mit dem SIGHUP macht eine Login-Shell, aber kein normaler Prozess. > Aber auch das passiert nicht! Was daher richtig ist. > Wenn ich meinem verwaisten Programm manuell ein SIGHUP sende, terminiert es > nämlich auch! Ja, was sonst. > Aber zurück zu Deiner Ausage: Der parent von meinem script.pl ist ja > apache. Dieser terminiert script.pl ja auch ordnungsgemäß, wenn die > Browserverbindung abreißt. Nur script.pl terminiert dabei nicht > programm! > Aber zurück zur Ausgangsfrage: Kann man ein cgi-Perlscript irgendwo so > gestalten (eine zusätzlich Anweisung oder ähnliches?), dass wenn es > ein entsprechende KILL-Signal von apache bekommt, auch ein kill-Signal > an seine Kinder weiterleitet, bevor es sich entgültig terminiert? Wenn dem so ist, dass apache seinem CGI-child ein Signal schickt (was ich nicht glaube), könntest du dies mit einem Signalhandler erreichen. Grüße Frank Seitz -- Dipl.-Inform. Frank Seitz Anwendungen für Ihr Internet und Intranet Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel Homepage: http://www.fseitz.de/ XING-Profil: http://www.xing.com/profile/Frank_Seitz2 |
|
#5
|
|||
|
|||
|
Frank Seitz wrote:
>>> Der Parent muss das also steuern, indem er prüft, ob die >>> Browserverbindung noch da ist. >> >> Also ich habe die Prozesse mal verfolgt: >> `-apache2---script.pl---programm >> >> Wenn ich jetzt den Browser stoppe, dann erbt init den Prozess >> programm. apache2 scheint also script.pl zu killen, was die Child- >> Prozesse von script.pl verwaisen lässt. > > Da stimmt was nicht. Meines wissens killt apache seine childs nicht. Ok, dann killt sich wohl script.pl selbst? Was passiert den mit den Ausgaben (print-Anweisungen) eines (weiter laufenden) cgi-Scriptes, wenn die Browserverbindung unterbrochen wurde? Verliert das Script vielleicht ein Pipe zu Apache und beendet sich deshalb oder wie wird das gesteuert? >> Laut meine Infos, sollte aber jedem verwaisten Prozess immer (von >> init?) ein SIGHUP gesendet werden? > > Das stimmt definitiv nicht. Der parent wird unterrichtet (SIGCHLD), > wenn sein child stirbt, aber nicht umgekehrt. Das mit dem SIGHUP > macht eine Login-Shell, aber kein normaler Prozess. ok, dann habe ich bei dem im Web gefunden Dokument zum Prozessmanagement wohl was falsch verstanden... So noch mal nachgeschaut: Du hast völlig recht, es handelt sich dabei nur um Prozesse die auf dem Terminal laufen. |
|
#6
|
|||
|
|||
|
Dominik Pusch wrote:
>>>> Der Parent muss das also steuern, indem er prüft, ob die >>>> Browserverbindung noch da ist. >>> >>> Also ich habe die Prozesse mal verfolgt: >>> `-apache2---script.pl---programm >>> >>> Wenn ich jetzt den Browser stoppe, dann erbt init den Prozess >>> programm. apache2 scheint also script.pl zu killen, was die Child- >>> Prozesse von script.pl verwaisen lässt. >> >> Da stimmt was nicht. Meines wissens killt apache seine childs >> nicht. > > Ok, dann killt sich wohl script.pl selbst? Was passiert den mit den > Ausgaben (print-Anweisungen) eines (weiter laufenden) cgi-Scriptes, > wenn die Browserverbindung unterbrochen wurde? Verliert das Script > vielleicht ein Pipe zu Apache und beendet sich deshalb oder wie wird > das gesteuert? So, Problem gelöst. Liegt wohl an Apache! Ich habe versucht ein ScriptLog zu erstellen mit der ScriptLog- Direktive. Das hat einfach nicht funktioniert. Habe in der apache config die Zeile "ScriptLog /tmp/cgi.log" hinzugefügt, weil in /tmp jeder User Schreibrecht hat (es stand extra dabei, dass das Scriptlog mit den Rechten des jeweiligen Users geschrieben wird). Bekam aber kein /tmp/cgi.log, selbst wenn ich im script absichtlich ein Fehler einbaue! Nach langer, verzweifelter Webrecherche habe ich ein Bugreport gelesen, wonach das Scriptlog bei dem Apache-Modul mod_cgi angeblich nicht funktioniert. Stattdessen soll man mod_cgid nehmen. Auch damit funktioniert bei mir das Scriptlog nicht. ABER: Damit verwaist mein Programm nicht mehr, sondern terminiert zusammen mit der script.pl! Also Problem gelöst, auch wenn ich immer noch nicht weiß, was genau der Unterschied zwischen mod_cgi und mod_cgid ist. Nochmals vielen Dank, Dominik |
|
#7
|
|||
|
|||
|
Dominik Pusch wrote:
> Frank Seitz wrote: >> >> Da stimmt was nicht. Meines wissens killt apache seine childs nicht. > > Ok, dann killt sich wohl script.pl selbst? Was passiert den mit den > Ausgaben (print-Anweisungen) eines (weiter laufenden) cgi-Scriptes, > wenn die Browserverbindung unterbrochen wurde? Verliert das Script > vielleicht ein Pipe zu Apache und beendet sich deshalb oder wie wird > das gesteuert? Der Kernel schickt dem Prozess ein SIGPIPE, wenn dieser auf eine geschlossene Pipe oder einen geschlossenen Socket schreibt. Daraufhin terminiert der Prozess (sofern er das Signal nicht besonders behandelt). Grüße Frank -- Dipl.-Inform. Frank Seitz Anwendungen für Ihr Internet und Intranet Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel Homepage: http://www.fseitz.de/ XING-Profil: http://www.xing.com/profile/Frank_Seitz2 |
|
|
|
|