Forum: PC-Programmierung FPC/Lazarus: Subprozeß unter Linux beenden


von BitPopler (Gast)


Lesenswert?

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

von Rolf M. (rmagnus)


Lesenswert?

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

von W.S. (Gast)


Lesenswert?

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.

von Rolf M. (rmagnus)


Lesenswert?

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.

von Jim M. (turboj)


Lesenswert?

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.

von Bitpopler (Gast)


Lesenswert?

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

von Bitpopler (Gast)


Lesenswert?

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  :)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.