我有一个基本上是无限循环的过程,还有第二个进程,它是一个定时器。一旦计时器完成,我如何才能杀死循环进程?
def action():
x = 0
while True:
if x < 1000000:
x = x + 1
else:
x = 0
def timer(time):
time.sleep(time)
exit()
loop_process = multiprocessing.Process(target=action)
loop_process.start()
timer_process = multiprocessing.Process(target=timer, args=(time,))
timer_process.start()
一旦计时器完成,我希望python脚本结束。
发布于 2019-02-28 08:38:04
您可以通过使用进程之间共享状态并创建所有并发进程都可以访问的标志值(尽管这可能有点低效)来实现。
以下是我的建议:
import multiprocessing as mp
import time
def action(run_flag):
x = 0
while run_flag.value:
if x < 1000000:
x = x + 1
else:
x = 0
print('action() terminating')
def timer(run_flag, secs):
time.sleep(secs)
run_flag.value = False
if __name__ == '__main__':
run_flag = mp.Value('I', True)
loop_process = mp.Process(target=action, args=(run_flag,))
loop_process.start()
timer_process = mp.Process(target=timer, args=(run_flag, 2.0))
timer_process.start()
loop_process.join()
timer_process.join()
print('done')
发布于 2019-02-28 08:01:46
在else
之后,action()
中的一个简单的返回语句将完美地工作。此外,您的timer
函数中有一个错误。您的论点与内置库时间具有相同的名称。
def action():
x = 0
while True:
if x < 1000000:
x = x + 1
else:
x = 0
return # To exit else it will always revolve in infinite loop
def timer(times):
time.sleep(times)
exit()
loop_process = multiprocessing.Process(target=action)
loop_process.start()
timer_process = multiprocessing.Process(target=timer(10))
timer_process.start()
希望这能回答你的问题!
发布于 2019-02-28 11:18:46
我认为你不需要为计时器做第二个过程。
优美超时
如果您需要在退出action
进程之前进行清理,您可以使用Timer
-thread并让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
超时终止
如果您不需要彻底关闭(您没有使用共享队列,使用DBs等),那么可以让父进程在指定的时间后对工作进程进行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。
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
https://stackoverflow.com/questions/54929482
复制相似问题