一、multiprocessing模块

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

看一下Process类的构造方法:

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

参数说明: 
group:进程所属组(基本不用) 
target:表示调用对象
args:表示调用对象的位置参数元组
name:别名 
kwargs:表示调用对象的字典

示例:

import multiprocessing

def 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(Process-1, initial)>]
Process-1 starting
worker 0
Process end.
[<Process(Process-1, stopped)>, <Process(Process-2, initial)>]
Process-2 starting
worker 1
Process end.
[<Process(Process-1, stopped)>, <Process(Process-2, stopped)>, <Process(Process-3, initial)>]
Process-3 starting
worker 2
Process end.
[<Process(Process-1, stopped)>, <Process(Process-2, stopped)>, <Process(Process-3, stopped)>, <Process(Process-4, initial)>]
Process-4 starting
worker 3
Process end.
[<Process(Process-1, stopped)>, <Process(Process-2, stopped)>, <Process(Process-3, stopped)>, <Process(Process-4, stopped)>, <Process(Process-5, initial)>]
Process-5 starting
worker 4
Process 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()函数

import time
from multiprocessing import Pool def run(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 in testFL:
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 in testFL:
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 in testFL:
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 import Pool
import time def fun_01(i):
time.sleep(2)
print('start_time:', time.ctime())
return i + 100 def fun_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 2019
end_time: 100 Thu Nov 14 16:31:41 2019
start_time: Thu Nov 14 16:31:41 2019
end_time: 101 Thu Nov 14 16:31:41 2019
start_time: Thu Nov 14 16:31:41 2019
end_time: 102 Thu Nov 14 16:31:41 2019
start_time: Thu Nov 14 16:31:43 2019
end_time: 103 Thu Nov 14 16:31:43 2019
done

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

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

import multiprocessing
import time def func(msg):
print('hello :', msg, time.ctime())
time.sleep(2)
print('end', time.ctime())
return 'done' + msg if __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 in result:
print('***:', res.get()) # get()函数得出每个返回结果的值 print('All end--')

运行结果:

五、多进程执行多个函数

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

示例:

import multiprocessing
import time
import os def Lee():
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()) def Marlon():
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()) def Allen():
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()) def Frank():
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 in func_list:
pool.apply_async(func) print('Waiting for all subprocesses done...')
pool.close()
pool.join()
print('All subprocesses done.')

运行结果:

parent process id 84172
Waiting for all subprocesses done... Run task Lee--84868******ppid:84172 ~~~~ Thu Nov 14 17:44:14 2019 Run task Marlon-84252******ppid:84172 ~~~~ Thu Nov 14 17:44:14 2019 Run task Allen-85344******ppid:84172 ~~~~ Thu Nov 14 17:44:14 2019 Run task Frank-85116******ppid:84172 ~~~~ Thu Nov 14 17:44:14 2019
Task Lee,runs 5.00 seconds. ~~~~ Thu Nov 14 17:44:19 2019
Task Marlon runs 10.00 seconds. ~~~~ Thu Nov 14 17:44:24 2019
Task Allen runs 15.00 seconds. ~~~~ Thu Nov 14 17:44:29 2019
Task Frank runs 20.00 seconds. ~~~~ Thu Nov 14 17:44:34 2019
All subprocesses done.

六、其他

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

Python进程池multiprocessing.Pool的用法的更多相关文章

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

    进程池: 进程池的使用有四种方式:apply_async.apply.map_async.map.其中apply_async和map_async是异步的,也就是启动进程函数之后会继续执行后续的代码不用 ...

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

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

  3. 【python小随笔】进程池 multiprocessing.Pool的简单实现与踩过的坑

    #导入进程模块 import multiprocessing #创建进程池 坑:一定要在循环外面创建进程池,不然会一直创建 pool = multiprocessing.Pool(30) for Si ...

  4. Python多进程池 multiprocessing Pool

    1. 背景 由于需要写python程序, 定时.大量发送htttp请求,并对结果进行处理. 参考其他代码有进程池,记录一下. 2. 多进程 vs 多线程 c++程序中,单个模块通常是单进程,会启动几十 ...

  5. python 进程池pool简单使用

    平常会经常用到多进程,可以用进程池pool来进行自动控制进程,下面介绍一下pool的简单使用. 需要主动是,在Windows上要想使用进程模块,就必须把有关进程的代码写if __name__ == ‘ ...

  6. Python程序中的进程操作-进程池(multiprocess.Pool)

    目录 一.进程池 二.概念介绍--multiprocess.Pool 三.参数用法 四.主要方法 五.其他方法(了解) 六.代码实例--multiprocess.Pool 6.1 同步 6.2 异步 ...

  7. python进程池剖析(一)

    python中两个常用来处理进程的模块分别是subprocess和multiprocessing,其中subprocess通常用于执行外部程序,比如一些第三方应用程序,而不是Python程序.如果需要 ...

  8. python进程池:multiprocessing.pool

    本文转至http://www.cnblogs.com/kaituorensheng/p/4465768.html,在其基础上进行了一些小小改动. 在利用Python进行系统管理的时候,特别是同时操作多 ...

  9. python 进程池Pool以及Queue的用法

    import os,time,random from multiprocessing import Pool def task(name): print('正在运行的任务:%s,PID:(%s)'%( ...

随机推荐

  1. 聊聊 print 的前世今生

    本文原创并首发于公众号[Python猫],未经授权,请勿转载. 原文地址:https://mp.weixin.qq.com/s/NuzfuH_zCZzcrmSFR04NHw (一) 上周,我翻译了一篇 ...

  2. Python基础-day01-3

    PyCharm 的初始设置(知道) 目标 恢复 PyCharm 的初始设置 第一次启动 PyCharm 新建一个 Python 项目 设置 PyCharm 的字体显示 PyCharm 的升级以及其他 ...

  3. python——模块(Module)的概念、使用以及安装第三方模块

    一.模块定义 python中,一个.py文件就是一个模块(Module). 使用模块的好处:1.提高了代码的可维护性.我们把函数进行分组,分别放在不同的模块中.2.编写代码不必要从0开始,当一个模块编 ...

  4. 基于windows server 2016和sqlserver 2016 AlwaysOn的群集配置

    文档:基于windows server 2016和sqlserver 2...链接:http://note.youdao.com/noteshare?id=4f07c1c3f7d0e32b7631d7 ...

  5. everspin自旋转矩MRAM技术

    MRAM的主体结构由三层结构的MTJ构成:自由层(free layer),固定层和氧化层.自由层与固定层的材料分别是CoFeB和MgO.MRAM 是一种非易失性的磁性随机存储器.它拥有静态随机存储器( ...

  6. <计算机系统结构中的8个伟大思想>

    摘自<计算机组成与设计>戴维帕森 ——面向摩尔定律的设计 ——使用抽象简化设计 ——加速大概率事件 ——通过并行提高性能 ——通过流水线提高性能 ——存储器层次 ——通过冗余提高可靠性

  7. .net上传文件,大文件及下载方式汇总(转)

    原文地址:http://www.360doc.com/content/19/1219/10/67993814_880731215.shtml Brettle.Web.NeatUpload.dll 文件 ...

  8. C lang: The caracter reverse

    Ax_Code #include<stdio.h> int main(void) { int i; char string[7] = {"mrsoft"}; char ...

  9. 1、netty入门说明

    netty中的例子,基本模式都是:server -> Initializer -> Handler . 在server中去启动线程,打开端口,设置initializer,和一些启动的参数配 ...

  10. Dotnetcore安装nuget包时不能使用content中的文件

    问题:用NUGET打包了一个asp.netcore的项目,试图安装到另一个asp.netcore项目中,除了自动添加引用外,还希望自动释放一些文件以供修改.这些操作以前在netframe中是正常的,脚 ...