ython学习笔记之多进程
最近项目中需要在Python中使用并行化,通常思路就是使用多线程实现,但是经过实践,发现多线程的实现相比没有多线程更慢一些(不知道是不是我写的有问题),查资料得知Python有一个GIL
锁,多线程实际上也只是在一个cpu核心上跑。
今天又来试了多进程的实现方式,果然速度快了很多。下面贴上部分代码:
Calculator.py文件
#coding:UTF-8
class Base():
#外部调用的方法,也是进程池的Master
@staticmethod
def execute_thread(arg):
import re
import multiprocessing
import correlation as corr
multiprocessing.freeze_support() # Windows 平台要加上这句,避免 RuntimeError
clist = re.split('@', arg.strip())
retstr = ''
results = []
#Pool()默认开启cpu核心数个进程——适合cpu密集型的计算,也可以加上参数,手动声明要创建的进程数
p = multiprocessing.Pool()
for cdata in clist:
#调用correlation.py文件中的work方法执行具体任务,参数为cdata,返回结果给result
result = p.apply_async(corr.work, args=(cdata,))
#结果保存到results中
results.append(result)
#阻止向进程池中继续添加任务
p.close()
#等待进程退出,在使用join()之前必须调用close()或者terminate()
p.join
retstr = ''
i = 0
#要在线程执行完之后遍历,
#如果在上面的循环中直接处理计算的结果,会导致进程池以阻塞的方式运行
for r in results:
a = r.get()
# print a
retstr = retstr + a
if i != len(results) -1:
retstr = retstr + '@'
i += 1
# if i < 10:
# print a
# print retstr
return retstr
correation.py
#coding:UTF-8
import re
import sys
import numpy as np
import math
#进程池中要执行的任务,可以直接将计算过程写在里面,这里为了方便阅读,改为调用另一个计算方法
def work(cdata):
val = re.split(';', cdata.strip())
return str(compute_corr(val[0], val[1]))
## x表示一个数组,y表示另一个数组或特征值
def compute_corr(xstr, ystr):
# 隐藏了计算过程
……
return returnstr
效果
任务数量 | 多进程方式耗时(S) | 没多进程方式耗时(S) |
---|---|---|
2540 | 0.55 | 1.12 |
10160 | 3.56 | 5.69 |
注意
上面的代码Python版本是2.7的,但是据说Python3的multiprocessing
模块api没有太多变化,所以应该也没问题,具体没有试过。
上面的代码在Linux(Ubuntu)上运行没有问题,但是在Windows上调用时有时会报错,暂时不知道具体原因,等知道后再来补充上。