本文参考“郭靖愕然——python的多线程与多进程”对多进程/多线程的概念进行理解,结合实际运用情况对python多进程进行整理。
一、进程与线程Process&Thread
进程 是操作系统进行资源分配的最小单元,资源包括CPU、内存、磁盘等IO设备等等,而 线程 是CPU调度的基本单位。举个简单的例子来帮助理解:我们电脑上同时运行的浏览器和视频播放器是两个不同的进程,进程可能包含多个子任务,这些子任务就是线程,比如视频播放器在播放视频时要同时显示图像、播放声音、显示字幕,这就是三个线程
多线程与多进程的执行方式是一样的,都是由操作系统在多个线程/进程之间快速切换,让每个线程/进程都短暂地交替运行,看起来就像同时执行一样。多线程/多进程使程序的执行速度和CPU的利用效率大大提升。绝大多数主流的编程语言都能很好地支持多线程,然而 python 由于 GIL 锁无法实现真正的多线程 。
python多线程和多进程不存在优劣之分,两者都有着各自的应用环境。线程几乎不占资源,系统开销少,切换速度快,而且同一个进程的多个线程之间能很容易地实现数据共享;而创建进程需要为它分配单独的资源,系统开销大,切换速度慢,而且不同进程之间的数据默认是不可共享的。
二、python实现多进程
使用multiprocessing模块创建Pool进程池
使用functools模块partial方法传入固定参数
# -*- coding: utf-8 -*-
'''
Created on 2019年5月28日
@author: H
'''
import time
from multiprocessing import Pool as ProcessPool
from functools import partial
import pandas as pd
import numpy as np
def Tpara(par4,x,y):
m,n,p,ti=par4
print(str(ti)+'...')
value=(m+n)*(p-x)/y
errorList=[m,n,p,value]
valueDF=pd.DataFrame([errorList],columns=['m','n','p','value'])
return valueDF
def main():
# wall time(即墙上时钟)time.time();CPU时间time.clock()
start=time.time()
start_run_time=str(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(start)))
print('start time : '+start_run_time)
# 获取Tpara()可变参数par4
para4=[]
mList=[7,8,9,10]
nList=[0.5,0.4,0.3,0.2,0.1]
pList=[0.6,0.7,0.8,0.9,1]
ti=0 #记录任务编号
for m in mList:
for n in nList:
for p in pList:
ti+=1
para4.append((m,n,p,ti))
poolNum=4 #进程数
p=ProcessPool(poolNum)
partial_work = partial(Tpara,x=3,y=5) #传入Tpara函数的固定参数
valueListIte = p.map(partial_work, para4) #传入Tpara函数的可变参数
p.close()
p.join()
#对全部任务的返回值进行汇总获取最大值
valueTDF=pd.DataFrame(columns=['m','n','p','value'])
for rangeNum in range(len(valueListIte)):
valueTDF=pd.concat([valueTDF,valueListIte[rangeNum]],ignore_index=True,axis=0)#axis默认0纵向拼接
MVPvalue=valueTDF.loc[valueTDF['value']==np.max(valueTDF['value'].astype(float))]#返回最大value所在行
print('==========valueTDF')
print(valueTDF)
print('==========MVPvalue')
print(MVPvalue)
end=time.time()
end_run_time=str(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(end)))
print('end time : '+end_run_time)
print('Running time : %s Seconds'%(end-start))
if __name__ == '__main__':
main()
运行结果: