1

我正在使用 python 的multiprocessing模块同时处理多个函数。每个衍生进程的函数都获取一些初始输入参数,以及一个Pipe将其结果发回的连接。由于各种原因,我必须使用像这样的单个进程,即Pool.map_async()-methods 之类的工具不可用。

有时,我需要终止一个需要很长时间才能完成的进程。

根据流程文档

警告:如果在相关进程正在使用管道或队列时使用此方法,则管道或队列可能会损坏并且可能无法被其他进程使用。类似地,如果进程获得了锁或信号量等,那么终止它很可能导致其他进程死锁。

我不担心第一部分,因为每个进程都有自己的管道对象,但是我如何确定一个进程是否“获得了锁或信号量”,和/或以对我的其余部分安全的方式终止程序?

4

3 回答 3

0

附带说明:检查为什么您的子流程“完成时间太长”可能是值得的。

至于警告,它与您何时“锁定”资源以供使用有关。例如:

# 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()。

于 2020-05-14T09:53:31.270 回答
0

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

好吧,如果有的话,你永远不会遇到这个。

如果您的实际需求能够证明这样做的成本是合理的,那么最好的解决方法是向可靠处理、设计稳健、弹性、自我修复系统的大师学习——比如在 NASA 运营的 Margaret HAMILTON 女士(麻省理工学院)阿波罗登月计划,将 AGC(阿波罗制导计算机)设计得如此正确和如此出色,它可以在自己的死锁风险中幸存下来,防止鹰着陆器坠毁月球表面。

最好的灵感来自,如果使用强大且独立的多节点对多节点通信平面框架 ZeroMQ 或 nanomsg 设计安全和自我修复的自治组件,pythonistas 可以使用它。

于 2020-05-14T09:54:35.407 回答
0

在 *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()
于 2020-05-14T10:08:39.797 回答