Hab das ganze nochmal überarbeitet...
http://trac.pylucid.net/browser/trunk/p ... y?rev=1634
Dabei ist zu beachten, das man stdout und stderr nur dann lesen kann, wenn der Prozess normal beendet wurde. Wurde der Process abgeschossen, blockiert das .read()...
Eine Idee wie man das umgehen kann???
EDIT: Link aktualisiert.
subprocess -> wann beendet?
Das Problem habe ich auch. Ich umgehe das einfach damit, dass ich .read() erst durchführe, wenn .returncode nicht gleich None ist (andernfalls greift sowieso der Timeout und killt den Prozess). Ich weiß aber nicht, wie viel Output dabei gepuffert wird.jens hat geschrieben:Wurde der Process abgeschossen, blockiert das .read()...
Ich mache übrigens noch eine kleine Unterscheidung in Windows und Unix/Mac:
Code: Alles auswählen
TIMEOUT = 3
PLATFORM = sys.platform
if PLATFORM == "win32":
import win32api
import win32con
import win32process
else:
import os
import signal
# ... somewhere else:
process = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
t = time.time()
while True:
process.poll()
if process.returncode is not None:
output = process.stdout.read()
returnCode = process.returncode
break
elif time.time() - t >= TIMEOUT:
# try to kill process
try:
if PLATFORM == "win32":
try:
h = win32api.OpenProcess(win32con.PROCESS_ALL_ACCESS, False, process.pid)
handle = h.handle
win32process.TerminateProcess(handle, 1)
killed = process.pid
except Exception, e:
killed = e
else:
try:
os.kill(process.pid, signal.SIGUSR1)
killed = process.pid
except Exception, e:
killed = e
finally:
break
time.sleep(0.5)
- Rebecca
- User
- Beiträge: 1662
- Registriert: Freitag 3. Februar 2006, 12:28
- Wohnort: DN, Heimat: HB
- Kontaktdaten:
Es gibt ja viele verschiedene Signale. SIGTERM (15) ist quasi die freundliche Bitte an den Prozess, sich ordnungsgemaess zu beenden. Der Prozess kann dann noch aufraeumen, koennte das Signal sogar ignorieren. IMO wird z.B. ein SIGTERM gesendet, wenn du im Fenster-Titel auf das "x" clickst.jens hat geschrieben:Warum, kannst du das näher erläutern? Ich kenne mich da nicht so richtig aus...lunar hat geschrieben:SIGTERM nutzen.
SIGKILL (9) hingegen ist ein hartes, sofortiges Abschiessen des Prozesses und sollte nur verwendet werden, wenn SIGTERM nicht mehr hilft.
Offizielles Python-Tutorial (Deutsche Version)
Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
So etwas hatte ich mir schon gedacht, aber ich wußte nicht welches signal die passendsten sind.Rebecca hat geschrieben:SIGKILL (9) hingegen ist ein hartes, sofortiges Abschiessen des Prozesses und sollte nur verwendet werden, wenn SIGTERM nicht mehr hilft.
Also dann könnte man es so machen, wie du vorgeschlagen hast. Nach dem timeout erstmal nur SIGTERM senden, dann nochmal einen timeout abwarten und nochmal SIGKILL hinterher schicken...
- Rebecca
- User
- Beiträge: 1662
- Registriert: Freitag 3. Februar 2006, 12:28
- Wohnort: DN, Heimat: HB
- Kontaktdaten:
So macht Linux das beim runterfahren auch.jens hat geschrieben:Also dann könnte man es so machen, wie du vorgeschlagen hast. Nach dem timeout erstmal nur SIGTERM senden, dann nochmal einen timeout abwarten und nochmal SIGKILL hinterher schicken...
Offizielles Python-Tutorial (Deutsche Version)
Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Ich hab meine Variante auf Basis von deinem umgestrickt. Nun auch ohne Threading und mit dem senden von zwei Signalen:droptix hat geschrieben:Ich mache übrigens noch eine kleine Unterscheidung in Windows und Unix/Mac:
https://github.com/jedie/PyLucid/blob/a ... rocess2.py
EDIT (jens): Link aktualisiert.
EDIT2: wieder aktualisiert