Ich versuche os.fork
zu verwenden, os.waitpid
und Gewinde einige zeitraubende Arbeit, um ein Kind Prozess zu schicken, wartet höchstens eine bestimmte Menge an Zeit für die Fertigstellung, und dann weitermachen und im Hintergrund laufen lassen. Es gibt auch einen sekundären Timer in dem Kind, das mich vom Laufen zu lange im Hintergrund verhindert, etwa so:Warten höchstens N Sekunden für ein fork'd Kind PID zu beenden
Fork execution
In the fork's child:
Start a thread to execute a task
If that thread runs for longer than X milliseconds:
thread.stop(), a custom method that softly stops the thread.
In the fork's parent:
If the child's PID stays running for longer than Y milliseconds:
return -1
else:
return 0
Nach Wert zurückkehrt, mag ich das Skript zu beenden. Das Kind kann und sollte weiterlaufen, wenn es nicht getan wird.
Der Code, den ich versucht habe (abgekürzt) ist:
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() #Sleeps for 30 seconds and ends.
thread1.start()
print "Started 1!"
timeout = X # say, 1000ms
while timeout > 0:
if not thread1.is_alive(): return "custom thread finished before the deadline!"
timeout -= 1
sleep(0.001)
if thread1.is_alive():
return "custom thread didn't finish before the deadline!"
thread1.stop()
exit()
else:
print pid
thread2 = Thread(target = os.waitpid, args = (pid, 0))
thread2.start()
print "Started 2!"
timeout2 = Y # say, 500ms
while timeout2 > 0:
if not thread2.is_alive(): return "child PID finished!"
timeout2 -= 1
sleep(0.001)
if thread2.is_alive():
return "child PID didn't finish yet!"
print test()
print "all done!"
Der Ausgang richtig ist, dass ich
bekommen1171
Started 2!
Started 1!
child PID didn't finish yet!
all done!
custom thread didn't finish before the deadline!
all done!
Aber dann das Skript nicht beendet! Es schläft für die restlichen 28 Sekunden vor
Wie mache ich die Hauptausführung dieses Skript abgeschlossen, nachdem die fork
Ed Eltern einen Wert zurückgibt? Wie ich bereits sagte, kann und sollte das Kind im Hintergrund laufen, es sollte die Ausführung der nächsten Aufgabe auf dem Elternteil nicht blockieren.
Ich interessiere mich wirklich nicht, wenn das Kind Ausgabe zum Standardausgang drucken kann - in der tatsächlichen Implementierung ist alles, was es macht, mit einer Datenbank zu sprechen, also muss es nichts interaktiv berichten. Das übergeordnete Element muss jedoch das untergeordnete Element abfertigen, höchstens Y Sekunden warten, bis das untergeordnete Objekt beendet ist, und dann (soweit der Skript aufgerufen wurde) die Ausführung des Skripts beenden, damit die nächste Aktion ausgeführt werden kann. Der andere Timer (X) ist nicht relevant, denke ich; es existiert nur, um das Kind davon abzuhalten, zu lange im Hintergrund zu laufen.
Irgendwelche Ideen? Ich nähere mich wahrscheinlich diesem total falsch, also "neu anfangen und es tun _ Weg" Ideen sind willkommen.
A [ 'threading.Thread'] (http: //docs.python .org/py3k/library/threading.html # thread-objects) Objekt hat keine vordefinierte 'stop' Methode. Woher kommt die "Stop" -Methode und was ist drin? Ich denke, wir müssen wissen, um diese Frage zu beantworten. – senderle
Eine Beispielklasse hinzugefügt. Der echte ist wesentlich länger, macht aber nichts besonders Einzigartiges (keine anderen Threads oder Subprozesse oder was auch immer). Der, den ich hinzugefügt habe, schläft für 30 Sekunden, nichts mehr. Das Ziel ist jedoch, dass das Programm AT Y Millisekunden zum Ausführen benötigt. Was auch immer das Deadline- und Stop() - Verhalten ist, es sollte im Hintergrund stattfinden. –
Warum müssen Sie einen Thread im Kind starten? Setzen Sie einfach einen Alarm, installieren Sie einen Signalhandler für SIGALRM mit einem einfachen Ausgang (0). Dann mach deine Arbeit im Kindprozess. Wenn der Timer abläuft, erhält der untergeordnete Prozess SIGALRM und wird beendet. Im Parent können Sie einen Signalhandler für SIGCHLD installieren (wenn das Kind den Kernel verlässt, wird der Signalhandler des Elternprozesses aufgerufen). – strkol