【问题标题】:Running Python on multiple cores在多核上运行 Python
【发布时间】:2017-08-25 18:38:14
【问题描述】:

我创建了一个(相当大的)程序,需要很长时间才能完成,我开始寻找加快程序速度的方法。

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

经过一番研究,我发现了这个网站: 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”(它甚至还没有完成!)

【问题讨论】:

  • 是的,因为你只有一个进程,所以它只会使用一个核心。
  • 另外,您使用的是numpy吗?因为那个链接似乎不相关。
  • 那么在 for 语句中必须执行大量乘法/减法的情况下,我将如何使用多个内核呢?例如for each in range(1000): a = a*each
  • 您如何测试/验证在多核上运行的?
  • @juanpa.arrivillaga 不,我没有使用 numpy,但我说它在我的场景中不起作用

标签: python python-3.x multiprocessing


【解决方案1】:

首先要回答您的第二个问题,“已完成”会打印到终端,因为 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.

更多信息,请参考以下链接:

【讨论】:

  • 惊人的答案。 +99999 ;)
猜你喜欢
  • 1970-01-01
  • 2011-11-24
  • 1970-01-01
  • 2011-08-28
  • 2017-05-26
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多