/bin/ps -A zeigt bereits beendete Programme an. Warum?
/bin/ps -A zeigt bereits beendete Programme an. Warum?
Debian, Lazarus 4.0RC1
Hallo!
Mein Hauptprogramm startet ein externes Programm mit TProcess.
Mein Hauptprogramm prüft, mithilfe von ps -A, ob das extern gestartete Programm noch läuft. (Wichtig ist eigentlich nur, die Ausgabe von ps -A)
Soweit funktioniert alles.
Der Benutzer beendet nun das extern gestartete Programm.
ps -A, zeigt das extern gestartete Programm aber nun weiterhin an, obwohl es beendet wurde.
Nun wird es noch komischer. Ich habe viel herumprobiert. Starte ich über das Hauptprogramm das externe Programm mehrmals, zeigt das ps -A auch an. Beende ich als Benutzer alle externen Programme, zeigt ps -A trotzdem alle an. Wiederhole ich das, zeigt ps -A immer mehr externe Programme an, wird aber niemals weniger.
Ich würde erwarten, wenn der Benutzer das extern gestartete Programm beendet, verschwindet auch der Programmname in ps -A. Dem ist aber nicht so.
Das externe Programm wird erst dann nicht mehr angezeigt, wenn ich das Hauptprogramm beende.
Warum?
Liebe Grüße
Epcop
Hallo!
Mein Hauptprogramm startet ein externes Programm mit TProcess.
Mein Hauptprogramm prüft, mithilfe von ps -A, ob das extern gestartete Programm noch läuft. (Wichtig ist eigentlich nur, die Ausgabe von ps -A)
Soweit funktioniert alles.
Der Benutzer beendet nun das extern gestartete Programm.
ps -A, zeigt das extern gestartete Programm aber nun weiterhin an, obwohl es beendet wurde.
Nun wird es noch komischer. Ich habe viel herumprobiert. Starte ich über das Hauptprogramm das externe Programm mehrmals, zeigt das ps -A auch an. Beende ich als Benutzer alle externen Programme, zeigt ps -A trotzdem alle an. Wiederhole ich das, zeigt ps -A immer mehr externe Programme an, wird aber niemals weniger.
Ich würde erwarten, wenn der Benutzer das extern gestartete Programm beendet, verschwindet auch der Programmname in ps -A. Dem ist aber nicht so.
Das externe Programm wird erst dann nicht mehr angezeigt, wenn ich das Hauptprogramm beende.
Warum?
Liebe Grüße
Epcop
- m.fuchs
- Lazarusforum e. V.
- Beiträge: 2805
- Registriert: Fr 22. Sep 2006, 19:32
- OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
- CPU-Target: x86, x64, arm
- Wohnort: Berlin
- Kontaktdaten:
Re: /bin/ps -A zeigt bereits beendete Programme an. Warum?
Kannst du mal deinen Quellcode zeigen, ein schneller Test bei mir(Lazarus 3.2, Linux Mint) war so wie du das erwartet hast.
Code: Alles auswählen
program ProcessTest;
{$MODE ObjFpc}
{$H+}
uses
Classes, SysUtils, Process;
var
p: TProcess;
begin
p := TProcess.Create(nil);
p.Executable := 'xed';
p.Options := p.Options + [poWaitOnExit];
p.Execute;
WriteLn('Waiting...');
ReadLn;
p.Free;
WriteLn('Bye...');
end.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
- fliegermichl
- Lazarusforum e. V.
- Beiträge: 1639
- Registriert: Do 9. Jun 2011, 09:42
- OS, Lazarus, FPC: Lazarus Fixes FPC Stable
- CPU-Target: 32/64Bit
- Wohnort: Echzell
Re: /bin/ps -A zeigt bereits beendete Programme an. Warum?
Wenn ein Programm andere Programme startet, so verbleiben diese als Zombies in der Prozessliste, bis der exit Status des Childprozesses abgefragt wurde.
Re: /bin/ps -A zeigt bereits beendete Programme an. Warum?
ps aux | grep 'Z'
STAT:
STAT:
D uninterruptible sleep (usually IO)
I Idle kernel thread
R running or runnable (on run queue)
S interruptible sleep (waiting for an event to complete)
T stopped by job control signal
t stopped by debugger during the tracing
W paging (not valid since the 2.6.xx kernel)
X dead (should never be seen)
Z defunct ("zombie") process, terminated but not reaped by its parent
Re: /bin/ps -A zeigt bereits beendete Programme an. Warum?
Gestartet habe ich es so:
Interessant, dass das bei Mint anders ist!?
Auch interessant. Das heißt, möchte man Wissen ob ein Prozess gestartet ist, reicht es nicht ps -A aufzurufen. Sondern, muss den Prozess auch über ps aux | grep 'Z' aufrufen. Und ggf. die Summe der gesuchten Prozesse von ps aux | grep 'Z' von der Summe der gesuchten Prozesse von ps -A abziehen. Erst dann hat man die tatsächlich laufenden Prozess(e).
Das mit dem Exit Status habe ich nicht verstanden.
Code: Alles auswählen
Process := TProcess.Create(nil);
try
Process.Executable := '../testprogramm';
Process.Parameters.Add(IntToStr(a)); //id
Process.Execute;
// ?? Process.ExitStatus;
// ?? Process.ExitCode;
finally
Process.Free;
end;
Code: Alles auswählen
ps aux | grep 'Z'
Das mit dem Exit Status habe ich nicht verstanden.
- m.fuchs
- Lazarusforum e. V.
- Beiträge: 2805
- Registriert: Fr 22. Sep 2006, 19:32
- OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
- CPU-Target: x86, x64, arm
- Wohnort: Berlin
- Kontaktdaten:
Re: /bin/ps -A zeigt bereits beendete Programme an. Warum?
Ist bei Mint nicht anders, dir fehlt eine Option die ich habe:Epcop hat geschrieben: Di 25. Mär 2025, 12:49Interessant, dass das bei Mint anders ist!?Code: Alles auswählen
Process.Executable := '../testprogramm'; Process.Parameters.Add(IntToStr(a)); //id Process.Execute;
Code: Alles auswählen
Process.Options := Process.Options + [poWaitOnExit];
Nachteil: dein Programm wartet an der Stelle, bis der Prozess beendet ist. Also müsstest du das ganze in einen Thread auslagern.
Vorteil: du kannst dir die Abfrage von ps ersparen, weil du auch so weißt ob der Prozess durch ist.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
Re: /bin/ps -A zeigt bereits beendete Programme an. Warum?
Hier ist erstmal eine Variante, die schonmal ganz gut aussieht:
Threads sind auch eine gute Idee. Aber für meine Anwendungsfall etwas übertrieben. Ich brauche das nur einmalig und selten.
Das mit ps war spannend, deswegen gleich Funktion gebaut. Dann kann es jeder nutzen wer mag
Code: Alles auswählen
function LaufendesProgrammZaehlen(const ExeName: string): Integer;
var
Process: TProcess;
Output: TStringList;
i: Integer;
ps_zaehler, zombie_zaehler: integer;
begin
Result := 0;
ps_zaehler := 0;
zombie_zaehler := 0;
// === Alle gesuchten Prozesse zählen
Process := TProcess.Create(nil);
Output := TStringList.Create;
try
Process.Executable := '/bin/ps'; // Für Windows genügt hier taskkill ?? Ohne ZombieProzesse
Process.Parameters.Add('-A'); // Windows braucht hier auch was anderes todo
Process.Options := Process.Options + [poWaitOnExit, poUsePipes];
Process.Execute;
Output.LoadFromStream(Process.Output);
// Zähle Vorkommen von ExeName in der Ausgabe
for i := 0 to Output.Count - 1 do
if Pos(ExeName, Output[i]) > 0 then
ps_zaehler := ps_zaehler+1;
finally
Process.Free;
Output.Free;
end;
// === Alle Zombie Prozesse zählen
Process := TProcess.Create(nil);
Output := TStringList.Create;
try
Process.Executable := '/bin/sh'; //ps -aux | grep "Z" geht nicht direkt! Muss über Shell laufen
Process.Parameters.Add('-c');
Process.Parameters.Add('ps -aux | grep "Z"');
Process.Options := Process.Options + [poWaitOnExit, poUsePipes];
Process.Execute;
Output.LoadFromStream(Process.Output);
// Zähle Vorkommen von ExeName in der Ausgabe
for i := 0 to Output.Count - 1 do
if Pos(ExeName, Output[i]) > 0 then
zombie_zaehler := zombie_zaehler+1;
finally
Process.Free;
Output.Free;
end;
Result := ps_zaehler-zombie_zaehler ;
ShowMessage('Anzahl der laufenden Instanzen von ' + ExeName + ': ' + IntToStr(Result));
end;
Das mit ps war spannend, deswegen gleich Funktion gebaut. Dann kann es jeder nutzen wer mag
