在多个核心上运行Python

时间:2017-08-25 18:38:14

标签: python python-3.x multiprocessing

我已经创建了一个(相当大的)程序,需要很长时间才能完成,我开始研究如何加快程序。

我发现如果在程序运行时打开任务管理器,则只使用一个核心。

经过一番研究,我找到了这个网站: Why does multiprocessing use only a single core after I import numpy?提供了os.system("taskset -p 0xff %d" % os.getpid())的解决方案, 但这对我不起作用,我的程序继续在单核上运行。

然后我发现了这个: is python capable of running on multiple cores?, 它指向使用多处理。

因此,在研究了多处理之后,我遇到了关于如何使用它的纪录片https://docs.python.org/3/library/multiprocessing.html#examples

我尝试了代码:

from multiprocessing import Process

def f(name):
    print('hello', name)

if __name__ == '__main__':
    p = Process(target=f, args=('bob',))
    p.start()
    p.join()

a = input("Finished")

运行代码后(不在IDLE中)它说:

Finished
hello bob
Finished

注意:说完之后我第一次按下

所以在此之后我现在更加困惑,我有两个问题

首先:它仍然没有运行多核(我有一个8核Intel i7)

第二:为什么在它甚至运行if语句代码之前输入“Finished”(它甚至还没有完成!)

1 个答案:

答案 0 :(得分:9)

要先回答您的第二个问题,“已完成”会打印到终端,因为a = input("Finished")位于您的if __name__ == '__main__':代码块之外。因此,它是一个模块级常量,在模块首次加载时分配,并在模块中的任何代码运行之前执行。

要回答第一个问题,您只创建了一个您运行的流程,然后等待完成再继续。这使得多处理没有任何好处,并且会产生创建新流程的开销。

因为你想创建几个进程,你需要通过某种集合(例如python列表)创建一个池,然后启动所有进程。

在实践中,您需要关注的不仅仅是处理器的数量(例如可用内存量,重新启动崩溃的工作人员的能力等)。但是,这是一个完成上述任务的简单示例。

import datetime as dt
from multiprocessing import Process, current_process
import sys

def f(name):
    print('{}: hello {} from {}'.format(
        dt.datetime.now(), name, current_process().name))
    sys.stdout.flush()

if __name__ == '__main__':
    worker_count = 8
    worker_pool = []
    for _ in range(worker_count):
        p = Process(target=f, args=('bob',))
        p.start()
        worker_pool.append(p)
    for p in worker_pool:
        p.join()  # Wait for all of the workers to finish.

    # Allow time to view results before program terminates.
    a = input("Finished")  # raw_input(...) in Python 2.

另请注意,如果您在启动工作人员后立即加入工作人员,则表示您正在等待每个工作人员在启动下一个工作人员之前完成其任务。除非必须按顺序排列任务,否则这通常是不合需要的。

通常错误

worker_1.start()
worker_1.join()

worker_2.start()  # Must wait for worker_1 to complete before starting worker_2.
worker_2.join()

通常需要

worker_1.start()
worker_2.start()  # Start all workers.

worker_1.join()
worker_2.join()   # Wait for all workers to finish.

有关详细信息,请参阅以下链接: