Python,多进程库问题

3

我是一名有益的助手,可以为您进行翻译。

我有一个程序,我希望可以并行运行其中的某个函数来处理多个参数。

该程序的格式如下:

import statements 

def function1():
     do something

def function2()
     do something

def main():

     function1()

我在网上找到了一些关于如何使用multiprocessing库的例子,比如下面的通用模板:

import multiprocessing

def worker(num):
    print 'Worker:', num
    return

if __name__ == '__main__':
    for i in range(5):
        p = multiprocessing.Process(target=worker, args=(i,))
        p.start()

据我所知,worker() 函数是用于并行执行的。但我不确定在何处或如何使用代码中的 (if __name__ == '__main__':) 块。
目前,这个块在我的 main() 中。运行程序时,我没有多次执行 worker 函数,而是多次执行我的主函数。
那么,正确的放置位置在哪里呢?应该把 (if __name__ == '__main__':) 块放在程序的最外层,而不是放在任何函数内部。

2
将并行逻辑(对multiprocessing的调用)放在main函数中。然后,在if __name__ == '__main__'内部调用main - inspectorG4dget
你需要展示你正在运行的实际代码。因为你展示的代码中根本没有调用你的 main() 函数,所以我们无法猜测为什么它会被调用。但是如果你按照你第二次发布的模板进行编写,你的代码将能够正常工作。 - Tim Peters
1个回答

2

将您提供的两个示例混合在一起,它会看起来像这样:

import multiprocessing

def worker(num):
    print 'Worker:', num
    return

def main():

    for i in range(5):
        p = multiprocessing.Process(target=worker, args=(i,))
        p.start()
        p.join()

if __name__ == '__main__':
     main()

worker替换为function1,即您想要并行化的任何一个函数。

关键部分是在if __name__ == '__main__':块中调用main函数,但在这个简单的例子中,您也可以将代码直接放在if __name__ == '__main__':下的def main():下面。

如果您永远不会从此文件导入任何内容,则甚至不需要if __name__ == '__main__':部分;只有在您希望能够将此脚本中的函数导入到其他脚本/交互式会话中而不运行main()代码时,才需要它。请参阅 if __name__ == "__main__": 是做什么的?

因此,最简单的用法是:

import multiprocessing

def worker(num):
    print 'Worker:', num
    return

for i in range(5):
    p = multiprocessing.Process(target=worker, args=(i,))
    p.start()
    p.join()

编辑:多进程池示例

import multiprocessing

def worker(num):
    #print 'Worker:', num
    return num

pool = multiprocessing.Pool(multiprocessing.cpu_count())

result = pool.imap(worker, range(5))

print list(result)

输出:

[0, 1, 2, 3, 4]

另请参见Python multiprocessing.Pool:何时使用apply、apply_async或map?以获取更详细的解释。


当我运行第一个版本时,它可以工作但是没有给我期望的输出结果,即工人:0,工人:1,工人:2...而是每次运行时顺序都不同,有时是(1, 2, 0, 4, 3),或者是(0, 3, 2, 1, 4)。此外,您提供的第二个版本如果没有if name == 'main':则会在我尝试运行它时一直运行下去。 - Mustard Tiger
顺序可能会变化,因为“多进程(multiprocessing)”将每个对“worker”的调用拆分为独立的进程,在多个核心上运行,而不关心调用进程的顺序、完成顺序和返回顺序。结果的返回顺序是按照它们完成的顺序,而不是它们被调用的顺序。如果您想保留顺序,请查看“multiprocessing.pool”和“apply_async”或“imap”https://docs.python.org/2/library/multiprocessing.html#examples。 - Harry
对于第二个版本,如果它不在函数块中,可能需要使用.join()。请参阅https://docs.python.org/2/library/multiprocessing.html#process-and-exceptions - Harry

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