如何在Python中为单个函数执行多进程?

5
我正在阅读Python 3的Multiprocessing主题,并尝试将该方法应用到我的脚本中,但是我收到了以下错误信息:

AttributeError: __ exit __

我使用Windows 7操作系统和i-7 8核处理器。我有一个大型shapefile需要使用所有8个内核进行处理(使用地图软件QGIS)。下面是我的代码,非常感谢您的帮助:
from multiprocessing import Process, Pool

def f():
    general.runalg("qgis:dissolve", Input, False, 'LAYER_ID', Output)

if __name__ == '__main__':
    with Pool(processes=8) as pool:
        result = pool.apply_async(f)

1
我会首先将f()的内容替换为例如print,以缩小问题范围。如果这一步通过了,那么general.runalg就有问题了。 - Tymoteusz Paul
@TymoteuszPaul - 谢谢,我会尝试这个方法。general.runal 单独使用时运行良好,所以我猜测问题可能与 Pool 方法有关。 - Joseph
你提到你是为Python3编写的,但你使用了2.7风格的print语句,这将会抛出一个错误。这可能是所有问题的原因 ;) - Tymoteusz Paul
@TymoteuszPaul - 我希望 :). 已经删除了 print 但仍然出现错误,所以将继续您的第一个建议。 - Joseph
1
在调用apply_async之前,是否已经定义了“dissolve”? - chown
@chown - 谢谢伙计,我很抱歉,但是dissolve在其他地方没有定义(我的错误)。我已经编辑了问题。 - Joseph
1个回答

3
multiprocessing.Pool的上下文管理器功能只在Python 3.3及以上版本中添加:

自版本3.3起:池对象现在支持上下文管理协议 - 请参阅上下文管理器类型。 __enter__()返回池对象,__exit__()调用terminate()

如果没有定义__exit__,则表明您正在使用3.2或更早版本。您需要手动调用Pool上的terminate以获得等效行为。
if __name__ == '__main__':
    pool = Pool(processes=8)
    try:
        result = pool.apply_async(f)
    finally:
        pool.terminate()

话虽如此,在这里您可能不想使用terminate(或者由此延伸的with语句)。Pool__exit__方法调用terminate,即使工作人员尚未完成工作,也会强制退出。您可能希望在退出之前实际等待工作者完成工作,这意味着您应该调用close(),然后使用join等待所有工作者完成工作后再退出:

if __name__ == '__main__':
    pool = Pool(processes=8)
    result = pool.apply_async(f)
    pool.close()
    pool.join()

太棒了,非常感谢!我可以在任务管理器中看到8个独立的进程正在运行。这个函数没有正确运行,但我认为这是我的问题,所以会尝试调整脚本。再次感谢! - Joseph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接