Ich versuche, os.fork
, os.waitpid
und das Threaden zu verwenden, um einige zeitaufwändige Arbeiten an einen Kindprozess zu übergeben, höchstens eine bestimmte Zeit auf dessen Abschluss zu warten und dann fortzufahren, während es im Hintergrund läuft. Im Kind gibt es auch einen sekundären Timer, der verhindert, dass es zu lange im Hintergrund läuft, und zwar so:
Ausführung des Forks
Im Kind des Forks:
Starten eines Threads, um eine Aufgabe auszuführen
Wenn dieser Thread länger als X Millisekunden läuft:
thread.stop(), eine benutzerdefinierte Methode, die den Thread sanft stoppt.
Im Elternteil des Forks:
Wenn die PID des Kindes länger als Y Millisekunden läuft:
return -1
sonst:
return 0
Nachdem ein Wert zurückgegeben wurde, möchte ich, dass das Skript beendet wird. Das Kind kann und sollte weiterlaufen, wenn es noch nicht beendet ist.
Der von mir ausprobierte Code (verkürzt) lautet:
class MyCustomThread(threading.Thread):
abort = False
def run(self):
counter = 0
while True:
if self.abort: break
counter += 1
if counter == 30: self.stop()
sleep(1)
return 0
def stop(self):
self.abort = True
def test():
X = 2000
Y = 500
pid = os.fork()
if pid == 0:
thread1 = MyCustomThread() #Schläft 30 Sekunden und endet.
thread1.start()
print "Gestartet 1!"
timeout = X # sagen wir, 1000ms
while timeout > 0:
if not thread1.is_alive(): return "benutzerdefinierter Thread wurde vor dem Ablauf der Frist beendet!"
timeout -= 1
sleep(0.001)
if thread1.is_alive():
return "benutzerdefinierter Thread wurde nicht vor Ablauf der Frist beendet!"
thread1.stop()
exit()
else:
print pid
thread2 = Thread(target = os.waitpid, args = (pid, 0))
thread2.start()
print "Gestartet 2!"
timeout2 = Y # sagen wir, 500ms
while timeout2 > 0:
if not thread2.is_alive(): return "Kind-PID beendet!"
timeout2 -= 1
sleep(0.001)
if thread2.is_alive():
return "Kind-PID wurde noch nicht beendet!"
print test()
print "alle erledigt!"
Die Ausgabe ist korrekt, denn ich erhalte
1171
Gestartet 2!
Gestartet 1!
Kind-PID wurde noch nicht beendet!
alle erledigt!
Benutzerdefinierter Thread wurde nicht vor Ablauf der Frist beendet!
alle erledigt!
Aber dann beendet sich das Skript nicht! Es schläft die verbleibenden 28 Sekunden, bevor es
Wie mache ich die Hauptausführung dieses Skripts nachdem der fork
te Elternteil einen Wert zurückgibt, beendet? Wie ich bereits sagte, sollte das Kind im Hintergrund weiterlaufen können und auch, aber die Ausführung der nächsten Aufgabe im Elternteil nicht blockieren.
Mir ist es wirklich egal, ob das Kind Ausgaben auf die Standardausgabe drucken kann - in der tatsächlichen Implementierung spricht es nur mit einer Datenbank, also muss es keine interaktiven Meldungen ausgeben. Der Elternteil muss jedoch das Kind beauftragen, höchstens Y Sekunden auf dessen Beendigung zu warten und dann (so weit wie derjenige, der das Skript aufgerufen hat, betroffen ist) die Ausführung des Skripts beenden, damit die nächste Aufgabe erledigt werden kann. Der andere Timer (X) ist meines Erachtens nicht relevant; er dient nur dazu, das Kind daran zu hindern, zu lange im Hintergrund zu laufen.
Irgendwelche Ideen? Wahrscheinlich gehe ich das Ganze total falsch an, also sind Ideen zum "Neuanfang und so machen" willkommen.