2017-08-25 71 views
2

我创建了一个(相当大的)程序,需要很长时间才能完成,我开始研究如何加速程序。在多个核心上运行Python

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

经过一番研究,我发现这个网站: 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核心英特尔酷睿i7)

二:为什么它输入在完成if语句代码之前“已完成”(并且它还没有完成!)

+0

是的,因为你只能有一个过程,所以它只会使用一个内核。 –

+0

另外,你使用'numpy'?因为那个链接似乎并不相关。 –

+0

那么如何在for语句中需要执行大量乘/减操作的情况下使用多核?例如'对于范围内的每个(1000):a = a * each' –

回答

2

要回答第二个问题,首先将“Finished”打印到终端,因为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. 

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

+0

令人惊叹的答案。 +99999;) –