【Python 多核并行计算】

  • Post author:
  • Post category:python


主要在WIN系统下实现:

首先检查一下电脑的实际核心数目:

在cmd.exe 中输入wmic然后输入cpu ge NumberOfCores 读取系统核心数目。

在这里插入图片描述

使用Python代码检查核心数

import multiprocessing as mp
import math
if __name__ == '__main__':
  numOfCore = int(mp.cpu_count())
  print(str(numOfCore))

在电脑上的输出结果并非6核心,而是12,那这台电脑一个核心可以执行多个任务,并且是一台可以超线程的电脑。



多个进程调用函数

下面的例子主要是用来了解一下进程调用函数的流程

下面的代码编译了几次感觉执行顺序都一样。

import multiprocessing as mp
def  working(i):
   print('Working process:%s' %i)
if __name__ == '__main__':
  ProcessWorker = []
  for i in range(12):
     p = mp.Process(target=working,args=(i,))
     ProcessWorker.append(p)
     p.start()
     p.join()

输出结果:

在这里插入图片描述

把它改成另外一种形式,明显的体会到有些进程会优先执行代码

import multiprocessing as mp
def  working(i):
   print('Working process:%s' %i)
if __name__ == '__main__':
  ProcessWorker = []
  for i in range(12):
     p = mp.Process(target=working,args=(i,))
     ProcessWorker.append(p)
     p.start()
  for i in range(12):
     p.join()

输出结果

在这里插入图片描述



使用Pool 类进行并行计算

Pool类可分为同步和异步

同步执行函数

1)Pool.map()

2)Pool.startmap()

3)Pool.apply()

异步执行函数

1)Pool.map_async()

2)Pool.startmap_async()

3)Pool.apply_async()

import multiprocessing as mp
import math
def  calculate(r):
   return r*r*math.pi
if __name__ == '__main__':
  with mp.Pool(8) as p:
      print(p.map(calculate,[1,3,5,7,9]))
  p.close();

运行结果

在这里插入图片描述



map与reduce

适合用于分而治之

并行计算需要知道怎么使用map 和 reduce

import multiprocessing as mp
from functools import reduce
import math
def sum(x,y):
    return x+y;
def  calculate(r):
   return r*r*math.pi
if __name__ == '__main__':
  with mp.Pool(8) as p:
      result=(p.map(calculate,[1,3,5,7,9]))
  p.close();
  result1 = reduce(sum,list(result))
  result2 = reduce(lambda x,y:x+y,list(result))
  print(result1)
  print(result2)

运行结果:

在这里插入图片描述



进程信息交互

利用队列Queue来进行信息交互,注意这个Queue是Manager下面的Queue,如果跑不动是因为用错方法。

from multiprocessing import Process,Lock,Pool,Manager
def put(value,q):
    q.put(value)
    print('put %s' % value)
def get(q):
    while True:
        if not q.empty():
          value = q.get()
          print('get %s' % value)
        else:
          break
if __name__=='__main__':
    m = Manager()
    q = m.Queue()
    pool = Pool(processes=6)
    for num in range(6):
      pool.apply_async(put,(num,q,))
    pool.close()
    pool.join()
    pget = Process(target=get,args=(q,))
    pget.start()
    pget.join()

运行结果:

在这里插入图片描述




当遇到资源抢占的情况,使用锁是最好的方法。有个程序不用锁等了2分钟才执行完,加了锁,需要排队等待资源反而使效率更高。

from multiprocessing import Process,Lock,Pool,Manager
lock = Lock()
def put(value,q):
    lock.acquire()
    q.put(value)
    print('put %s' % value)
    lock.release()

def get(q):
    while True:
        if not q.empty():
          value = q.get()
          print('get %s' % value)
        else:
          break
if __name__=='__main__':
    m = Manager()
    q = m.Queue()
    pool = Pool(processes=6)
    for num in range(6):
      pool.apply_async(put,(num,q,))
    pool.close()
    pool.join()
    pget = Process(target=get,args=(q,))
    pget.start()
    pget.join()

输出结果:

在这里插入图片描述



版权声明:本文为wangmingshi666原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。