[英]Safe way to terminate a python subprocess?
我正在使用 python 的multiprocessing
模块同时处理多个函数。 每个衍生进程的 function 都会获得一些初始输入 arguments 和Pipe
连接以将其结果发回。 由于各种原因,我必须使用像这样的单个进程,即像Pool.map_async()
这样的工具 - 方法不在桌面上。
有时,我需要终止一个需要很长时间才能完成的进程。
根据流程文档:
警告:如果在关联进程使用 pipe 或队列时使用此方法,则 pipe 或队列可能会损坏并且可能无法被其他进程使用。 类似地,如果进程获得了锁或信号量等,那么终止它很可能导致其他进程死锁。
我不担心第一部分,因为每个进程都有自己的 pipe object,但是我如何确定一个进程是否“获得了锁或信号量” ,和/或以对我的其余部分安全的方式终止程序?
问: “终止python 子进程的安全方法?”
好吧,如果有的话,你永远不会遇到这个。
如果您的实际需求可以证明这样做的成本是合理的,那么最好的解决方法是向可靠处理、设计强大、弹性、自我修复系统的大师学习——比如在 NASA 运营的 Margaret HAMILTON 女士(麻省理工学院)阿波罗登月计划,将 AGC(阿波罗制导计算机)设计得如此正确和如此出色,它可以在自身的死锁风险中幸存下来,防止鹰着陆器坠毁月球表面。
最好的灵感来自分布式计算,如果使用强大且独立的多节点到多节点通信平面框架 ZeroMQ 或 nanomsg 设计安全和自我修复的自治组件,pythonistas 可以使用它。
附带说明:检查为什么您的子流程“完成时间太长”可能是值得的。
至于警告,它与您何时“锁定”资源以供使用有关。 例如:
# function to withdraw from account
def withdraw(balance, lock):
for _ in range(10000):
lock.acquire()
balance.value = balance.value - 1
lock.release()
来源: https://www.geeksforgeeks.org/synchronization-pooling-processes-python/
如果您在子进程执行lock.acquire()
lock.release()
终止子进程,您将遇到死锁情况。
所以问题是,您是否在要终止的进程中使用任何 threading.Lock 或 threading.Semaphore 对象?
我希望这有助于理解终止子进程/线程是否安全。
编辑:顺便说一句,您还应该考虑使用 kill() 而不是 terminate()。
在 *nix 上,您可以尝试将 SIGINT 发送到进程而不是终止/杀死它并捕获 KeyboardInterrupt 异常以进行清理:
from multiprocessing import Process
import os
import time
import signal
def f():
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
print('Do the emergency cleanup here')
p = Process(target=f)
p.start()
os.kill(p.pid, signal.SIGINT)
p.join()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.