Я думаю, вам не нужно делать второй процесс только для таймера.
Graceful Timeout
В случае, если вам нужно очистить перед выходом в процессе action
, выможет использовать Timer
-поток и позволить циклу while проверить, жив ли он еще.Это позволяет вашему рабочему процессу корректно завершиться, но вам придется платить с пониженной производительностью, потому что повторный вызов метода занимает некоторое время.Не должно быть проблем, если это не жесткий цикл.
from multiprocessing import Process
from datetime import datetime
from threading import Timer
def action(runtime, x=0):
timer = Timer(runtime, lambda: None) # just returns None on timeout
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
Завершение по таймауту
Если вам не нужно закрывать clean (вы не используете общие очереди, не работаете с БД и т. Д.), Вы можете разрешить родительскому процессу terminate()
рабочий процесс послеВаше указанное время.
terminate ()
Завершить процесс.В Unix это делается с помощью сигнала SIGTERM;в Windows используется TerminateProcess ().Обратите внимание, что обработчики выхода и предложения finally и т. Д. Не будут выполняться.
Обратите внимание, что процессы-потомки процесса не будут завершены - они просто станут осиротевшими.
ПредупреждениеЕсли этот метод используется, когда связанный процесс использует канал или очередь, то канал или очередь могут быть повреждены и могут стать непригодными для использования другим процессом.Точно так же, если процесс получил блокировку или семафор и т. Д., То его завершение может привести к взаимоблокировке других процессов. документы
Если вам не нужно ничего делать с родителем, вы можете просто .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
-thread внутри родительского элемента дляthat.
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