【问题标题】:Initializing and destroying Python multiprocessing workers初始化和销毁​​ Python 多处理工作者
【发布时间】:2012-10-14 08:38:03
【问题描述】:

我有一个模型,我从 Python 中多次调用它。该模型需要很长时间才能启动和关闭,但处理输入数据的时间很短(可以在启动/关闭之间多次完成)。多处理 Pool() 似乎是完成这项工作的好方法,但我无法让 Model() 类正确销毁。

下面给出了程序代码的简化结构。实际上,init 和 del 函数需要用 win32com.client 模块做一些巧妙的事情,而 model.y 变量是一个控制外部应用程序的句柄。

#!/usr/bin/env python

import multiprocessing
import random
import time

class Model():
    def __init__(self):
        self.y = random.randint(0,5) # simplification
        time.sleep(5) # initialisation takes a while...
    def __del__(self):
        del(self.y) # simplification
        time.sleep(1) # destruction isn't especially quick either

def init():
    global model
    model = Model()

def f(x): # worker function, runs quickly
    return model.y * x ** 2

def main():
    pool = multiprocessing.Pool(processes=2, initializer=init)
    it = pool.imap(f, range(4))
    for n in range(4):
        print it.next()
    pool.close()

if __name__ == '__main__':
    main()

Model() 永远不会调用 del 函数,我猜是因为垃圾收集器中保存了一些引用。如何确保模型在程序结束时正确关闭?

【问题讨论】:

标签: python multiprocessing


【解决方案1】:

johnthexiii 的解决方案会在工作函数的第一次运行时终止模型。您可以提供单独的销毁功能:

import time

def g(x): # destroy function
    del model
    time.sleep(1) # to ensure, this worker does not pick too many
    return None

pool.close() 之前添加

pool.map_async(g, range(2), 1) # if specified to have two processes before

我不认为,这是一个非常“干净”的解决方案,但它应该可以工作。

【讨论】:

  • 什么是阻止池中的单个工作人员声称多个关闭请求,而其他人没有收到?
  • 由于您的关机被认为很慢(并且增加了 1 秒的额外等待时间)并且块大小设置为 1,我假设每个工作人员都会收到一个关机请求,但是不能保证。
【解决方案2】:

怎么样

def f(x): # worker function, runs quickly
    y = model.y
    del model
    return y * x ** 2

【讨论】:

  • 正如 Sebastian 指出的那样,每次调用 f(x) 时都会杀死模型。我需要每个 worker 启动,多次运行 f(x),然后优雅地关闭。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-18
  • 2023-03-30
  • 1970-01-01
  • 2012-04-14
  • 2013-08-13
  • 2018-11-12
  • 1970-01-01
相关资源
最近更新 更多