使用multiprocessing模块充分利用所有核心
我有两段代码,正在用来学习Python 3.1中的多进程。我的目标是让所有可用的处理器都用上100%。但是,这里展示的代码片段只能达到30%到50%的使用率。
有没有办法让Python“强制”使用100%?是操作系统(Windows 7,64位)限制了Python对处理器的访问吗?当下面的代码片段在运行时,我打开任务管理器,看到处理器的使用率有波动,但从来没有达到并保持在100%。此外,我还看到多个python.exe进程在不断创建和销毁。这些进程和处理器有什么关系呢?比如说,如果我启动了4个进程,每个进程并没有使用自己的核心。那么,这些进程到底在用什么呢?它们是共享所有核心吗?如果是的话,是操作系统在强制这些进程共享核心吗?
代码片段 1
import multiprocessing
def worker():
#worker function
print ('Worker')
x = 0
while x < 1000:
print(x)
x += 1
return
if __name__ == '__main__':
jobs = []
for i in range(50):
p = multiprocessing.Process(target=worker)
jobs.append(p)
p.start()
代码片段 2
from multiprocessing import Process, Lock
def f(l, i):
l.acquire()
print('worker ', i)
x = 0
while x < 1000:
print(x)
x += 1
l.release()
if __name__ == '__main__':
lock = Lock()
for num in range(50):
Process(target=f, args=(lock, num)).start()
6 个回答
10
下面是一个用纯Python写的最简单的例子:
def f(x):
while 1:
# ---bonus: gradually use up RAM---
x += 10000 # linear growth; use exponential for faster ending: x *= 1.01
y = list(range(int(x)))
# ---------------------------------
pass # infinite loop, use up CPU
if __name__ == '__main__': # name guard to avoid recursive fork on Windows
import multiprocessing as mp
n = mp.cpu_count() * 32 # multiply guard against counting only active cores
with mp.Pool(n) as p:
p.map(f, range(n))
使用方法:在寒冷的日子里热身(不过你可以把这个循环改成其他更有意义的东西)。
注意:如果想退出程序,不要拔掉插头或按住电源键,应该按Ctrl-C。
21
你可以使用psutil
这个库来把通过multiprocessing
创建的每个进程固定到特定的CPU上,简单来说,就是让某个程序只在某个处理器上运行。
import multiprocessing as mp
import psutil
def spawn():
procs = list()
n_cpus = psutil.cpu_count()
for cpu in range(n_cpus):
affinity = [cpu]
d = dict(affinity=affinity)
p = mp.Process(target=run_child, kwargs=d)
p.start()
procs.append(p)
for p in procs:
p.join()
print('joined')
def run_child(affinity):
proc = psutil.Process() # get self pid
print(f'PID: {proc.pid}')
aff = proc.cpu_affinity()
print(f'Affinity before: {aff}')
proc.cpu_affinity(affinity)
aff = proc.cpu_affinity()
print(f'Affinity after: {aff}')
if __name__ == '__main__':
spawn()
注意:正如评论中提到的,psutil.Process.cpu_affinity
在macOS系统上是不可用的。
49
要充分利用所有的处理器核心,尽量不要频繁地创建和销毁新的进程。
每个核心可以创建几个进程,并把它们通过管道连接起来。
在操作系统层面,这些通过管道连接的进程会同时运行。
你写的代码越少(而且越多地依赖操作系统),就越有可能充分利用所有的资源。
python p1.py | python p2.py | python p3.py | python p4.py ...
这样做可以最大限度地利用你的CPU。