我认为你不需要为计时器单独创建第二个进程。
优雅的超时
如果您的“操作”进程需要在退出之前进行清理,则可以使用“Timer”线程,并让while循环检查其是否仍然存活。这允许您的工作进程优雅地退出,但您必须付出一些性能代价,因为重复的方法调用需要一些时间。不过,如果它不是一个紧密的循环,这并不是问题。
from multiprocessing import Process
from datetime import datetime
from threading import Timer
def action(runtime, x=0):
timer = Timer(runtime, lambda: None)
timer.start()
while timer.is_alive():
if x < 1_000_000_000:
x += 1
else:
x = 0
if __name__ == '__main__':
RUNTIME = 1
p = Process(target=action, args=(RUNTIME,))
p.start()
print(f'{datetime.now()} {p.name} started')
p.join()
print(f'{datetime.now()} {p.name} ended')
示例输出:
2019-02-28 19:18:54.731207 Process-1 started
2019-02-28 19:18:55.738308 Process-1 ended
超时终止
如果您不需要进行干净的关闭(未使用共享队列,与数据库等交互),则可以让父进程在指定时间后终止()
工作进程。
terminate()
终止进程。在Unix上,使用SIGTERM信号;在Windows上,使用TerminateProcess()。请注意,退出处理程序和finally子句等将不会执行。
请注意,进程的子孙进程不会被终止-它们只会变成孤儿进程。
警告:如果该方法在关联进程正在使用管道或队列时使用,则管道或队列可能会损坏,并且可能无法被其他进程使用。同样,如果进程已经获得了锁或信号量等,则终止进程可能会导致其他进程死锁。docs
如果父进程没有其他任务,您可以简单地.join(timeout)
工作进程,然后.terminate()
。
from multiprocessing import Process
from datetime import datetime
def action(x=0):
while True:
if x < 1_000_000_000:
x += 1
else:
x = 0
if __name__ == '__main__':
RUNTIME = 1
p = Process(target=action)
p.start()
print(f'{datetime.now()} {p.name} started')
p.join(RUNTIME)
p.terminate()
print(f'{datetime.now()} {p.name} terminated')
示例输出:
2019-02-28 19:22:43.705596 Process-1 started
2019-02-28 19:22:44.709255 Process-1 terminated
如果你想使用 terminate()
,但需要让父进程解除阻塞,你也可以在父进程中使用一个 Timer
线程来实现。
from multiprocessing import Process
from datetime import datetime
from threading import Timer
def action(x=0):
while True:
if x < 1_000_000_000:
x += 1
else:
x = 0
def timeout(process, timeout):
timer = Timer(timeout, process.terminate)
timer.start()
if __name__ == '__main__':
RUNTIME = 1
p = Process(target=action)
p.start()
print(f'{datetime.now()} {p.name} started')
timeout(p, RUNTIME)
p.join()
print(f'{datetime.now()} {p.name} terminated')
示例输出:
2019-02-28 19:23:45.776951 Process-1 started
2019-02-28 19:23:46.778840 Process-1 terminated
Threading.Timer
可能会比将计时作为单独的进程来处理,减少一些开销。 - martineau