Hallo zusammen,
ich habe ein Problem, das ich noch nicht ganz verstehe. 2
Konsolen-Programme:
1.) slave : wird gestartet, macht was, beendet bei SIGINT bzw Strg-C
Beim Beenden schreibt er noch Einstellungen in Dateien, das kann 1-2s
dauern.
2.) master: startet slave. Wenn master beendet werden soll, soll er auch
slave (kontrolliert) beenden.
slave wird mit TProcess gestartet. Options sind versuchsweise
mittlerweile von [poUsePipes] aufgeblasen auf
[poUsePipes,poStderrToOutPut,poDefaultErrorMode]. (poUsePipes brauche
ich, weil ich den Standard-Out auslese)
Leider ändern die Options am Problem nichts: slave beendet sich nicht.
Habe schon folgende Varianten probiert:
1
fpkill(proc.ProcessID,2);
2
/bin/kill als Subprozeß ausgeführt
3
proc.Terminate(0);
Terminate() ist das einzige, was zum Ende des Prozesses führt. Aber da
hat slave doch gar keine Chance zu reagieren und z.B. noch Dateien zu
Ende zu schreiben, oder?
In der Konsole bekomme ich für master und slave PIDs angezeigt. kill -2
an den Slave zeigt keinerlei Reaktion (?!?). kill -15 auch nicht.
kill -9 geht, aber das ist effektiv wieder die Panzerfaust wie
Terminate();
Könnt ihr mir einen Tipp geben, wo ich geistig falsch abgebogen bin? Ist
das eine Eigenschaft von Linux oder bin ich nur zu blöd? (OK,
gefährliche Frage...)
OS ist Linux Mint auf PC.
Danke schon mal und viele Grüße
Andy
BitPopler schrieb:> Leider ändern die Options am Problem nichts: slave beendet sich nicht.
Sicher, dass er sich nicht beendet? Fragst du den Exit-Status des
Prozesses ab? Wenn nicht, ist es ggf. ein Zombie. Schau mal mit ps nach,
ob der Prozess als "defunct" markiert ist.
Siehe https://de.wikipedia.org/wiki/Zombie-Prozess
BitPopler schrieb:> ich habe ein Problem, das ich noch nicht ganz verstehe.
Nun ja, im Grunde brauchst du einen Mechanismus, der dem untergeordneten
Programm sagt, daß es sich selber beenden soll, aber keinen
Holzhammer, der es zwangsweise ohne sein Zutun beendet.
Aber warum bloß machst du dein Konstrukt aus 2 separaten Programmen?
Würde es nicht völlig ausreichen, wenn du in einem einzigen Programm 2
Threads aufmachst? Da kannst du ganz bequem die Threads miteinander
kommunizieren lassen und obige Nachricht zum Beenden von einem an den
anderen senden.
W.S.
W.S. schrieb:> BitPopler schrieb:>> ich habe ein Problem, das ich noch nicht ganz verstehe.>> Nun ja, im Grunde brauchst du einen Mechanismus, der dem untergeordneten> Programm sagt, daß es sich selber beenden soll, aber keinen> Holzhammer, der es zwangsweise ohne sein Zutun beendet.
Die Signale, die er bereits verwendet, sind genau solch ein Mechanismus,
wenn es eben nicht gerade das Signal 9 (SIGKILL) ist, das er ja zu
vermeiden versucht.
Prozess Ende ist normalerweise sigterm (Nummer 15) und nicht sigint (2).
Das Signal SigTerm kann man noch im Prozess abfangen und aufräumen. Das
geht bei sigKill(9) nicht mehr.
Hi zusammen und vielen Dank für Eure Antworten!
Das mit den 2 Programmen liegt daran, daß der slave das Programm ist,
was ich gerne zu bestimmten Bedingungen und Zeiten starten und beenden
möchte. Da es nicht mein eigenes Programm (closed-source) ist, geht halt
nur mit Subprozeß ;)
Wenn ich slave auf Konsole starte und Strg+C drücke, meldet er Signal 2
(SIGINT) und fährt kontrolliert herunter. Wenn ich bei meinem Programm
Strg+C drücke, springt er zumindest meinen Signal-Handler mit sig=2 an.
Insofern war ich auf SIGINT fixiert.
SIGTERM hatte ich auch mal ausprobiert, aber das hat genauso (nicht)
funktioniert wir SIGINT. SIGKILL will ich natürlich vermeiden, das ist
mir zu "spontan-final".
Ich habe für mich jetzt einen workaround gefunden. Wenn ich im master
bei SIGINT auf den Input-Pipe vom Slave char(3) (=> Strg+C) schreibe,
dann meldet slave wieder brav signal2 und fährt herunter.
Ob das jetzt eine allgemeingültige Lösung ist oder nur der slave komisch
programmiert ist, weiß ich nicht.
Auch wenn ich jetzt für mich das Problem gelöst habe, würde mich
trotzdem interessieren, worüber ich jetzt eigentlich gestolpert bin. Ist
das eine Eigenart von Linux, die ich in den man-pages überlesen habe?
Oder wirklich nur pech gehabt mit einer exotischen Implementierung des
Slaves?
Letzteres ist Schicksal, aus ersterem könnte ich lernen und mir nächstes
Mal neue Fehler ausdenken :)
Danke nochmal und ein schönes Wochenende!
Andy
Rolf M. schrieb:> BitPopler schrieb:>> Leider ändern die Options am Problem nichts: slave beendet sich nicht.>> Sicher, dass er sich nicht beendet? Fragst du den Exit-Status des> Prozesses ab? Wenn nicht, ist es ggf. ein Zombie. Schau mal mit ps nach,> ob der Prozess als "defunct" markiert ist.> Siehe https://de.wikipedia.org/wiki/Zombie-Prozess
P.S. ich warte mit Wait auf den proc.waitonexit() auf den Prozeß.
Die Idee mit dem Zombie hatte ich ganz am Anfang auch mal, aber der
Prozeß zeigt immer noch alle von außen meßbaren Lebenszeichen
(Prozessor-Zeit, seriellen Schnittstelle, Erreichbarkeit über
Netzwerk...)
kurz: #5 lebt :)