python - 如何在另一个子进程完成时终止正在运行的子进程(在多处理中)

标签 python multiprocessing

我遇到了多处理问题:

class PythonHelper(object):
    @staticmethod
    def run_in_parallel(*functions):
        processes=list()
        for function in functions:
            process=Process(target=function)
            process.start()
            processes.append(process)
        for process in processes:
            process.join()

我使用上述静态方法来同时运行多个函数(将它们组合在一个进程中)。一切都很好,直到我遇到需要在“子进程”之一终止时强制终止进程。

例如:

from PythonHelper import PythonHelper as ph
from Recorder import Recorder

class Logger(object):

    def run_recorder_proc(self):
        rec=Recorder()
        rec.record_video()

    def run_printer_proc(self):
    #hypothetical function: execution takes a long time
        for i in range(9000000):
            print("number: {}".format(i))

    def run_logger(self):
        ph.run_in_parallel(self.run_printer_proc,self.run_recorder_proc)

self.run_printer_procself.run_recorder_proc 是我的子进程。如何在其中一个子进程完成时“杀死”剩余的子进程?

<小时/>

编辑: 完整源代码:

class PythonHelper(object):
    @staticmethod
    #with your fix
    def run_in_parallel(*functions):
        processes={}
        for function in functions:
            process=Process(target=function)
            process.start()
            processes[process.pid]=process
        # wait for any process to complete
        pid, status = os.waitpid(-1, 0)
        # one process terminated
        # join it
        processes[pid].join()
        del processes[pid]
        # terminate the rest
        for process in processes.values():
            process.terminate()
        for process in processes.values():
            process.join()


class Logger(object):
    def run_numbers_1(self):
        for i in range(900000):
            print("number: {}".format(i))
    def run_numbers_2(self):
        for i in range(100000):
            print("number: {}".format(i))
    def run_logger(self):
        ph.run_in_parallel(self.run_numbers_1,self.run_numbers_2)

if __name__=="__main__":
    logger=Logger()
    logger.run_logger()

根据上面的示例,我想在 run_numbers_2 完成时强制终止 run_numbers_1

最佳答案

您可以通过稍微更改 run_in_parallel() 来实现这一点:

def run_in_parallel(*functions):
    processes={}
    for function in functions:
        process=Process(target=function)
        process.start()
        processes[process.pid]=process
    # wait for any process to complete
    pid, status = os.waitpid(-1, 0) 
    # one process terminated
    # join it
    processes[pid].join()
    del processes[pid]
    # terminate the rest
    for process in processes.itervalues():
        process.terminate()
    for process in processes.itervalues():
        process.join()

[更新] 根据您的完整代码,这里是一个工作示例。它使用 Event 对象,而不是容易出现竞争的 os.waitpid(),其他进程在完成时设置该对象:

from multiprocessing import Process, Event

class MyProcess(Process):
    def __init__(self, event, *args, **kwargs):
        self.event = event
        Process.__init__(self, *args, **kwargs)

    def run(self):
        Process.run(self)
        self.event.set()

class PythonHelper(object):
    @staticmethod
    #with your fix
    def run_in_parallel(*functions):
        event = Event()
        processes=[]
        for function in functions:
            process=MyProcess(event, target=function)
            process.start()
            processes.append(process)
        # wait for any process to complete
        event.wait()
        # one process completed
        # terminate all child processes
        for process in processes:
            process.terminate()
        for process in processes:
            process.join()


class Logger(object):
    def run_numbers_1(self):
        for i in range(90000):
            print("1 number: {}".format(i))
    def run_numbers_2(self):
        for i in range(10000):
            print("2 number: {}".format(i))
    def run_logger(self):
        PythonHelper.run_in_parallel(self.run_numbers_1,self.run_numbers_2)

if __name__=="__main__":
    logger=Logger()
    logger.run_logger()

关于python - 如何在另一个子进程完成时终止正在运行的子进程(在多处理中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8095944/

相关文章:

python - 升级到 18.1 后无法将 --extra-index-url 与 pip 一起使用

python - 为什么Tornado的ioloop和httpserver的性能有差异?

python - Python multiprocessing.Process 子类的属性

python - 多进程池中apply_async的问题

python - 如何使用 Keras.to_Categorical 在 dataFrame 中一次对多列进行 One-Hot 编码?

python - Unicode解码错误: 'ascii' codec can't decode byte 0xff in position 0: ordinal not in range(128)

python - 如何在作为参数传递的函数发生异常后获取完整的堆栈跟踪?

python - Python 的 multiprocessing.Pool 是否支持远程子进程?

c# - 如何锁定网络上的文件(在 Windows 中)?

python - 如何在 python 中使用多处理为变量分配新值