繁体   English   中英

终止 python 子进程的安全方法?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM