一、multiprocessing模块

multiprocessing模块提供了一个Process类来代表一个进程对象,multiprocessing模块像线程一样管理进程,这个是multiprocessing的核心,它与threading很相似,对多核CPU的利用率会比threading好的多

看一下Process类的构造方法:

__init__(self, group=None, target=None, name=None, args=(), kwargs={})

参数说明:

group:进程所属组(基本不用)

target:表示调用对象

args:表示调用对象的位置参数元组

name:别名

kwargs:表示调用对象的字典

示例:

importmultiprocessingdef do(n): #参数n由args=(1,)传入

name = multiprocessing.current_process().name #获取当前进程的名字

print(name, 'starting')print("worker", n)return

if __name__ == '__main__':

numList=[]for i in range(5):

p= multiprocessing.Process(target=do, args=(i,)) #(i,)中加入","表示元祖

numList.append(p)print(numList)

p.start()#用start()方法启动进程,执行do()方法

p.join() #等待子进程结束以后再继续往下运行,通常用于进程间的同步

print("Process end.")

运行结果:

[]

Process-1starting

worker 0

Process end.

[, ]

Process-2starting

worker1Process end.

[, , ]

Process-3starting

worker2Process end.

[, , , ]

Process-4starting

worker3Process end.

[, , , , ]

Process-5starting

worker4Process end.

通过打印numList可以看出当前进程结束后,再开始下一个进程

注意:

在Windows上要想使用进程模块,就必须把有关进程的代码写在当前.py文件的if __name__ == ‘__main__’ :语句的下面,才能正常使用Windows下的进程模块。Unix/Linux下则不需要

二、Pool类

Pool类可以提供指定数量的进程供用户调用,当有新的请求提交到Pool中时,如果池还没有满,就会创建一个新的进程来执行请求。如果池满,请求就会告知先等待,直到池中有进程结束,才会创建新的进程来执行这些请求

下面介绍一下multiprocessing 模块下的Pool类下的几个方法:

1.apply()

函数原型:apply(func[, args=()[, kwds={}]])

该函数用于传递不定参数,同python中的apply函数一致,主进程会被阻塞直到函数执行结束(不建议使用,并且3.x以后不再出现)

2.apply_async

函数原型:apply_async(func[, args=()[, kwds={}[, callback=None]]])

与apply用法一致,但它是非阻塞的且支持结果返回后进行回调

3.map()

函数原型:map(func, iterable[, chunksize=None])

Pool类中的map方法,与内置的map函数用法行为基本一致,它会使进程阻塞直到结果返回

注意:虽然第二个参数是一个迭代器,但在实际使用中,必须在整个队列都就绪后,程序才会运行子进程

4.map_async()

函数原型:map_async(func, iterable[, chunksize[, callback]])

与map用法一致,但是它是非阻塞的

5.close()

关闭进程池(pool),使其不再接受新的任务

6.terminal()

结束工作进程,不再处理未处理的任务

7.join()

主进程阻塞等待子进程的退出, join方法要在close或terminate之后使用

示例1--使用map()函数

importtimefrom multiprocessing importPooldefrun(fn):#fn: 函数参数是数据列表的一个元素

time.sleep(1)print(fn *fn)if __name__ == "__main__":

testFL= [1, 2, 3, 4, 5, 6]print('shunxu:') #顺序执行(也就是串行执行,单进程)

s =time.time()for fn intestFL:

run(fn)

t1=time.time()print("顺序执行时间:", int(t1 -s))print('concurrent:') #创建多个进程,并行执行

pool = Pool(3) #创建拥有3个进程数量的进程池

#testFL:要处理的数据列表,run:处理testFL列表中数据的函数

pool.map(run, testFL)

pool.close()#关闭进程池,不再接受新的进程

pool.join() #主进程阻塞等待子进程的退出

t2 =time.time()print("并行执行时间:", int(t2 - t1))

运行结果:

1、map函数中testFL为可迭代对象--列表

2、当创建3个进程时,会一次打印出3个结果“1,4,9”,当当创建2个进程时,会一次打印出2个结果“1,4”,以此类推,当创建多余6个进程时,会一次打印出所有结果

3、如果使用Pool(),不传入参数,可以创建一个动态控制大小的进程池

从结果可以看出,并发执行的时间明显比顺序执行要快很多,但是进程是要耗资源的,所以平时工作中,进程数也不能开太大。 对Pool对象调用join()方法会等待所有子进程执行完毕,调用join()之前必须先调用close(),让其不再接受新的Process了

示例2--使用map()_async函数

print('concurrent:') #创建多个进程,并行执行

pool = Pool(3) #创建拥有3个进程数量的进程池

#testFL:要处理的数据列表,run:处理testFL列表中数据的函数

pool.map_async(run, testFL)

pool.close() #关闭进程池,不再接受新的进程

pool.join() #主进程阻塞等待子进程的退出

t2 =time.time()print("并行执行时间:", int(t2 - t1))

运行结果:

从结果可以看出,map_async()和map()用时相同。目前还没有看出两者的区别,后面知道后再完善

示例3--使用apply()函数

print('concurrent:') #创建多个进程,并行执行

pool = Pool(3) #创建拥有3个进程数量的进程池

#testFL:要处理的数据列表,run:处理testFL列表中数据的函数

for fn intestFL:

pool.apply(run, (fn,))

pool.close()#关闭进程池,不再接受新的进程

pool.join() #主进程阻塞等待子进程的退出

t2 =time.time()print("并行执行时间:", int(t2 - t1))

运行结果:

可见,使用apply()方法,并行执行和顺序执行用时相同,经过试验,进程数目增大也不会减少并行执行的时间

原因:以阻塞的形式产生进程任务,生成1个任务进程并等它执行完出池,第2个进程才会进池,主进程一直阻塞等待,每次只执行1个进程任务

示例4--使用apply_async()函数

print('concurrent:') #创建多个进程,并行执行

pool = Pool(3) #创建拥有3个进程数量的进程池

#testFL:要处理的数据列表,run:处理testFL列表中数据的函数

for fn intestFL:pool.apply_async(run, (fn,))

pool.close()#关闭进程池,不再接受新的进程

pool.join() #主进程阻塞等待子进程的退出

t2 =time.time()print("并行执行时间:", int(t2 - t1))

运行结果:

可见,使用apply_async()方法,并行执行时间与使用map()、map_async()方法相同

注意:

map_async()和map()方法,第2个参数可以是列表也可以是元祖,如下图:

而使用apply()和apply_async()方法时,第2个参数只能传入元祖,传入列表进程不会被执行,如下图:

三、apply_async()方法callback参数的用法

示例:

from multiprocessing importPoolimporttimedeffun_01(i):

time.sleep(2)print('start_time:', time.ctime())return i + 100

deffun_02(arg):print('end_time:', arg, time.ctime())if __name__ == '__main__':

pool= Pool(3)for i in range(4):

pool.apply_async(func=fun_01, args=(i,), callback=fun_02) #fun_02的入参为fun_01的返回值

#pool.apply_async(func=fun_01, args=(i,))

pool.close()

pool.join()print('done')

运行结果:

start_time: Thu Nov 14 16:31:41 2019end_time:100 Thu Nov 14 16:31:41 2019start_time: Thu Nov14 16:31:41 2019end_time:101 Thu Nov 14 16:31:41 2019start_time: Thu Nov14 16:31:41 2019end_time:102 Thu Nov 14 16:31:41 2019start_time: Thu Nov14 16:31:43 2019end_time:103 Thu Nov 14 16:31:43 2019done

map_async()方法callback参数的用法与apply_async()相同

四、使用进程池并关注结果

importmultiprocessingimporttimedeffunc(msg):print('hello :', msg, time.ctime())

time.sleep(2)print('end', time.ctime())return 'done' +msgif __name__ == '__main__':

pool= multiprocessing.Pool(2)

result=[]for i in range(3):

msg= 'hello %s' %i

result.append(pool.apply_async(func=func, args=(msg,)))

pool.close()

pool.join()for res inresult:print('***:', res.get()) #get()函数得出每个返回结果的值

print('All end--')

运行结果:

五、多进程执行多个函数

使用apply_async()或者apply()方法,可以实现多进程执行多个方法

示例:

importmultiprocessingimporttimeimportosdefLee():print('\nRun task Lee--%s******ppid:%s' % (os.getpid(), os.getppid()), '~~~~', time.ctime())

start=time.time()

time.sleep(5)

end=time.time()print('Task Lee,runs %0.2f seconds.' % (end - start), '~~~~', time.ctime())defMarlon():print("\nRun task Marlon-%s******ppid:%s" % (os.getpid(), os.getppid()), '~~~~', time.ctime())

start=time.time()

time.sleep(10)

end=time.time()print('Task Marlon runs %0.2f seconds.' % (end - start), '~~~~', time.ctime())defAllen():print("\nRun task Allen-%s******ppid:%s" % (os.getpid(), os.getppid()), '~~~~', time.ctime())

start=time.time()

time.sleep(15)

end=time.time()print('Task Allen runs %0.2f seconds.' % (end - start), '~~~~', time.ctime())defFrank():print("\nRun task Frank-%s******ppid:%s" % (os.getpid(), os.getppid()), '~~~~', time.ctime())

start=time.time()

time.sleep(20)

end=time.time()print('Task Frank runs %0.2f seconds.' % (end - start), '~~~~', time.ctime())if __name__ == '__main__':

func_list=[Lee, Marlon, Allen, Frank]print('parent process id %s' %os.getpid())

pool= multiprocessing.Pool(4)for func infunc_list:

pool.apply_async(func)print('Waiting for all subprocesses done...')

pool.close()

pool.join()print('All subprocesses done.')

运行结果:

parent process id 84172Waitingforall subprocesses done...

Run task Lee--84868******ppid:84172 ~~~~ Thu Nov 14 17:44:14 2019Run task Marlon-84252******ppid:84172 ~~~~ Thu Nov 14 17:44:14 2019Run task Allen-85344******ppid:84172 ~~~~ Thu Nov 14 17:44:14 2019Run task Frank-85116******ppid:84172 ~~~~ Thu Nov 14 17:44:14 2019Task Lee,runs5.00 seconds. ~~~~ Thu Nov 14 17:44:19 2019Task Marlon runs10.00 seconds. ~~~~ Thu Nov 14 17:44:24 2019Task Allen runs15.00 seconds. ~~~~ Thu Nov 14 17:44:29 2019Task Frank runs20.00 seconds. ~~~~ Thu Nov 14 17:44:34 2019All subprocesses done.

六、其他

1、获取当前计算机的CPU数量

python 多进程 调用模块内函数_Python进程池multiprocessing.Pool的用法相关推荐

  1. python 多进程 调用模块内函数_python--多进程的用法详解实例

    想让python实现多进程(multiprocessing),我们要先区分不同的操作系统的不同之处. Linux操作系统下提供了一个fork()系统调用,普通函数调用一次返回一次,fork()调用一次 ...

  2. python 多进程 调用模块内函数_进程创建fork()和multiprocessing模块Process类

    一.进程VS程序 一个人穿上军装去打仗就是战士,战士需要武器.战场等资源.一个人去种田就是农民,农民需要土地.锄头等资源. 编写完毕的代码,安静的呆在磁盘上,称之为程序.代码要运行就得加载到内存,正在 ...

  3. python 多进程 调用模块内函数_python子进程模块subprocess详解与应用实例 之一

    分类: Python/Ruby 2014-09-09 10:59:42 subprocess--子进程管理器 一.subprocess 模块简介 subprocess最早是在2.4版本中引入的. su ...

  4. python 进程池 等待数量_python 进程池multiprocessing.Pool

    44.Python 进程池multiprocessing.Pool 最后更新于:2020-03-21 11:53:37 python进程池Pool 和前面讲解的python线程池 类似,虽然使用多进程 ...

  5. Python进程池multiprocessing.Pool的用法

    一.multiprocessing模块 multiprocessing模块提供了一个Process类来代表一个进程对象,multiprocessing模块像线程一样管理进程,这个是multiproce ...

  6. Python 进程池 multiprocessing.Pool - Python零基础入门教程

    目录 一.Python 进程池 multiprocessing.Pool 介绍 二.Python 进程池 multiprocessing.Pool 使用 三.猜你喜欢 零基础 Python 学习路线推 ...

  7. python进阶之进程池multiprocessing.Pool

    python的进程池multiprocessing.Pool有八个重要函数: apply.apply_async.map.map_async.imap.imap_unordered.starmap.s ...

  8. python中的进程池:multiprocessing.Pool()

    python中的进程池: 我们可以写出自己希望进程帮助我们完成的任务,然后把任务批量交给进程池 进程池帮助我们创建进程完成任务,不需要我们管理. 进程池:利用multiprocessing 下的Poo ...

  9. python进程池multiprocessing.Pool和线程池multiprocessing.dummy.Pool实例

    本文简单介绍python进程模块multiprocessing提供的进程池和线程池功能. 进程池: 进程池的使用有四种方式:apply_async.apply.map_async.map.其中appl ...

最新文章

  1. webview Java与JS互调
  2. Blender钢铁机器人建模与动画全流程制作视频教程
  3. 实现一个模拟CMD.exe命令编辑模式执行与显示的Delphi控件
  4. 网页性能优化之异步加载js文件
  5. Linux下通过进程名查询占用的端口
  6. socket连接 代码
  7. ajax获取php cookie,Ajax 无法跨域获取 cookie
  8. Java - 为什么要使用接口编程【转】
  9. yzmcms图片自适应代码_[ NeurIPS 2020 ] 一叶知秋 —— 基于“单目标域样本”的领域自适应方法...
  10. windows10大瘦身 - 关闭lync的日志记录
  11. CC254x--API
  12. Linux学习总结(34)——Linux系统目录结构详解
  13. 全国专业技术人员计算机应用能力考试word2003题库版,全国专业技术人员计算机应用能力考试word2003...
  14. 【语音分析】基于matlab语音线谱对转换【含Matlab源码 560期】
  15. 微服务框架Jersey:快速入门
  16. 在Markdown中插入图片及图注的方法
  17. 在Ubuntu 16.04 中将应用添加到系统服务中
  18. 字符串的常用方法和常用类
  19. 小卡机器人积木教程_这个会动的智能积木机器人分分钟让孩子爱不释手!秒杀家中99%的益智玩具!| 团...
  20. android 源代码分析 绘制,Android源码分析(View的绘制流程)

热门文章

  1. Roller5.0.3安装配置部署 step by step
  2. 阿里云人工智能ET夺肺结节诊断世界冠军
  3. 删除 Ceph 的image报rbd: error: image still has watchers
  4. Linux小细节-1
  5. RabbitMQ之Exchange分类
  6. 共济失调对我们的危害你知道吗
  7. jdk自带的Unicode转utf8工具
  8. Cisco 3550配置DHCP的实际经验
  9. 禁用Cookie在web浏览器中读取/写入c#应用程序
  10. Spring SetFactoryBean实例