python之multiprocessing创建进程
python的multiprocessing模块是用来创建多进程的,下面对multiprocessing总结一下使用记录。
multiprocessing创建多进程在windows和linux系统下的对比
fork()
import ospid = os.fork() # 创建一个子进程if pid == 0: print('这是子进程') print(os.getpid(),os.getppid())else: print('这是父进程') print(os.getpid())os.wait() # 等待子进程结束释放资源
fork函数被调用后会返回两次,pid为0的代表子进程,其他返回子进程的id号表示父进程。
getpid和getppid函数可以获取本进程和父进程的id号;
fork方式的缺点:
兼容性差,只能在类linux系统下使用,windows系统不可使用;
扩展性差,当需要多条进程的时候,进程管理变得很复杂;
会产生“孤儿”进程和“僵尸”进程,需要手动回收资源。
优点:
是系统自带的接近低层的创建方式,运行效率高。
Process创建进程
创建方式一:
from multiprocessing import Queue, Processimport osdef test():time.sleep(2)print('this is process {}'.format(os.getpid()))if __name__ == '__main__':p = Process(target=test)p.start() # 子进程 开始执行p.join() # 等待子进程结束print('ths peocess is ended')
创建方式二:
from multiprocessing import Queue, Processimport osclass MyProcess(Process):def run(self):time.sleep(2)print('this is process {}'.format(os.getpid())) def __del__(self):print('del the process {}'.format(os.getpid()))if __name__ == '__main__':p = MyProcess()p.start()print('ths process is ended')# 结果:ths process is ended this is process 7600del the process 7600del the process 12304
说明:
Process对象可以创建进程,但Process对象不是进程,其删除与否与系统资源是否被回收没有直接的关系。
上例看到del方法被调用了两次,Process进程创建时,子进程会将主进程的Process对象完全复制一份,这样在主进程和子进程各有一个Process对象,但是p1.start()启动的是子进程,主进程中的Process对象作为一个静态对象存在。
主进程执行完毕后会默认等待子进程结束后回收资源,不需要手动回收资源;
join()函数用来控制子进程结束的顺序,主进程会阻塞等待子进程结束,其内部也有一个清除僵尸进程的函数,可以回收资源;
当子进程执行完毕后,会产生一个僵尸进程,其会被join函数回收,或者再有一条进程开启,start函数也会回收僵尸进程,所以不一定需要写join函数。
windows系统在子进程结束后会立即自动清除子进程的Process对象,而linux系统子进程的Process对象如果没有join函数和start函数的话会在主进程结束后统一清除。
Process对象分析
class Process(object):def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):pass # Process对象是python用来创建进程的类 group:扩展保留字段; target:目标代码,一般是我们需要创建进程执行的目标函数。 name:进程的名字,如果不指定会自动分配一个; args:目标函数的普通参数; kwargs:目标函数的键值对参数;# 方法 start():创建一个子进程并执行,该方法一个Process实例只能执行一次,其会创建一个进程执行该类的run方法。 run():子进程需要执行的代码; join():主进程阻塞等待子进程直到子进程结束才继续执行,可以设置等待超时时间timeout. terminate():使活着的进程终止; is_alive():判断子进程是否还活着。
进程池Pool
如果需要创建大量的进程,就需要使用Pool了。
from multiprocessing import Queue, Process, Poolimport osdef test():time.sleep(2)print('this is process {}'.format(os.getpid()))def get_pool(n=5):p = Pool(n) # 设置进程池的大小for i in range(10):p.apply_async(test)p.close() # 关闭进程池p.join()if __name__ == '__main__':get_pool()print('ths process is ended')
分析:厦门厦工叉车怎么样?
如上,进程池Pool被创建出来后,即使实际需要创建的进程数远远大于进程池的最大上限,p1.apply_async(test)代码依旧会不停的执行,并不会停下等待;相当于向进程池提交了10个请求,会被放到一个队列中;
当执行完p1 = Pool(5)这条代码后,5条进程已经被创建出来了,只是还没有为他们各自分配任务,也就是说,无论有多少任务,实际的进程数只有5条,计算机每次最多5条进程并行。
当Pool中有进程任务执行完毕后,这条进程资源会被释放,pool会按先进先出的原则取出一个新的请求给空闲的进程继续执行;
当Pool所有的进程任务完成后,会产生5个僵尸进程,如果主线程不结束,系统不会自动回收资源,需要调用join函数去回收。
join函数是主进程等待子进程结束回收系统资源的,如果没有join,主程序退出后不管子进程有没有结束都会被强制杀死;
创建Pool池时,如果不指定进程最大数量,默认创建的进程数为系统的内核数量.
Pool对象分析
class Pool(object):def __init__(self, processes=None, initializer=None, initargs=(),maxtasksperchild=None, context=None):pass # 初始化参数 processes:进程池的大小,默认cpu内核的数量 initializer:创建进程执行的目标函数,其会按照进程池的大小创建相应个数的进程; initargs:目标函数的参数 context:代码的上下文# 方法 apply():使用阻塞方式调用func; apply_async():使用非阻塞方式条用func; close():关闭Pool,使其不再接受新的任务; terminate():不管任务是否完成,立即终止; join():主进程阻塞,等待子进程的退出,必须在close()后面使用; map(self, func, iterable, chunksize=None):多进程执行一个函数,传入不同的参数; starmap(self, func, iterable, chunksize=None):和map类似,但iterable参数可解压缩; starmap_async(self, func, iterable, chunksize=None, callback=None,error_callback=None):使用异步的方式的starmap,callback为返回后的处理函数 map_async(self, func, iterable, chunksize=None, callback=None,error_callback=None):异步方式的map
实例
from multiprocessing import Poolimport osdef test(n):time.sleep(1)print('this is process {}'.format(os.getpid())) return ndef test1(n, m):print(n, m)print('this is process {}'.format(os.getpid()))def back_func(values): # 多进程执行完毕会返回所有的结果的列表print(values)def back_func_err(values): # 多进程执行完毕会返回所有错误的列表print(values)def get_pool(n=5):p = Pool(n) # p.map(test, (i for i in range(10))) # 阻塞式多进程执行# p.starmap(test1, zip([1,2,3],[3,4,5])) # 阻塞式多进程执行多参数函数# 异步多进程执行函数p.map_async(test, (i for i in range(5)), callback=back_func, error_callback=back_func_err) # 异步多进程执行多参数函数p.starmap_async(test1, zip([1,2,3],[3,4,5]), callback=back_func, error_callback=back_func_err)print('-----')p.close()p.join()if __name__ == '__main__':get_pool()print('ths process is ended')
进程锁
进程虽然不像线程那样共享内存的数据,而是每个进程有单独的内存,但多进程也是共享文件系统的,即硬盘系统;当多进程同时写入文件操作时,可能造成数据的破坏,因此进程也存在同步锁。
from multiprocessing import Pool, Lockmuex = Lock()def test(): if muex.acquire():f = open('./test_pro.txt', 'r+', encoding='utf-8')x = f.read() if not x:f.write('0') else:f.seek(0)f.write(str(int(x)+1))f.close()muex.release()if __name__ == '__main__':p = Pool(5) for i in range(10):p.apply_async(test)p.close()p.join() with open('./test_pro.txt', 'r+', encoding='utf-8') as f:print(f.read())
进程锁可以保证文件系统的安全,但是它使得并行变成了串行,效率下降了,也可能造成死锁问题,一般避免用锁机制。
参考
https://docs.python.org/
转载于:https://www.cnblogs.com/xyou/p/9577030.html
python之multiprocessing创建进程相关推荐
- python 多进程multiprocessing进程池pool tensorflow-yolov3 报错 MemoryError
进程数设置为1-9个都能正常运行,设置成10个就开始报错,怪事! D:\20191031_tensorflow_yolov3\python\python.exe D:/20191031_tensorf ...
- python process 函数_Python Process创建进程的2种方法详解
前面介绍了使用 os.fork() 函数实现多进程编程,该方法最明显的缺陷就是不适用于 Windows 系统.本节将介绍一种支持 Python 在 Windows 平台上创建新进程的方法. Pytho ...
- Python创建进程、线程的两种方式
代码创建进程和线程的两种方式 很多人学习python,不知道从何学起. 很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手. 很多已经做案例的人,却不知道如何去学习更加高深的知识. ...
- Python创建进程的四种方式
Python创建进程的四种方式 百度百科 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构 ...
- Python创建进程类Process
1. Python创建进程类Process python的multiprocessing模块提供了一个创建进程的类Precess,其创建有以下两种方法: 创建Process类的实例,并指向目标函数和传 ...
- python 结束进程 terminate_【Python】multiprocessing.Process.terminate()结束子进程将导致子进程无法执行finally块,如何解决?...
我在使用multiprocessing库创建进程的时候,发现了这么一个问题: https://docs.python.org/3.5/library/multiprocessing.html#mult ...
- python multiprocessing — 基于进程的并行
概述 multiprocessing 是一个用与 threading 模块相似API的支持产生进程的包. multiprocessing 包同时提供本地和远程并发,使用子进程代替线程,有效避免 Glo ...
- python之操作系统介绍,进程的创建
操作系统(英语:operating system,缩写作 OS)是管理计算机硬件与软件资源的计算机程序,同时也是计算机系统的内核与基石.操作系统需要处理如管理与配置内存.决定系统资源供需的优先次序.控 ...
- Python | 面试必问,线程与进程的区别,Python中如何创建多线程?
其实关于元类还有很多种用法,比如说如何在元类当中设置参数啦,以及一些规约的用法等等.只不过这些用法比较小众,使用频率非常低,所以我们 不过多阐述 了,可以在用到的时候再去详细了解.我想只要大家理解了元 ...
最新文章
- win 常用网络命令
- python基础30个常用代码大全-Python3列表内置方法大全及示例代码小结
- python基础知识资料-Python基础知识篇 列表简介
- bzoj1096 [ZJOI2007]仓库建设
- python能做大型游戏吗_python有做大型游戏的潜力吗?
- 利用Python进行数据分析笔记-时间序列(时区、周期、频率)
- 手机验证码登录 添加 区号,国家,国家简写,国家中文名称,国旗展示
- PNP问题学习笔记1
- spring boot社区疫苗接种管理系统毕业设计源码281442
- 美团分布式mysql_9种分布式ID生成之美团(Leaf)实战
- onos中引入外部依赖
- 【镜像复现】开源围棋AI—— ikataGo 快速复现教程
- 专访王博,国内资深游戏3D角色美术大神
- 《图解HTTP》--返回结果的HTTP状态码
- JAVA修炼秘籍第六章《鏖战》
- ip-guard产品功能介绍
- 【树莓派学习笔记】树莓派4B上运行uboot并从网络启动linux内核(上)
- 2021年N1叉车司机考试及N1叉车司机报名考试
- LAMMPS模拟——纳米螺旋桨
- 一米鲜已获得其1500万美元Pre-B轮融资
热门文章
- php rsa数字签名为空,如何使用PHP将数字签名(RSA,证书等)添加到任何文件?
- linux下如何删除整行文本格式,Shell中如何删除文本比较长的行的实现方法
- matlab preloadfcn,simulink中打不开SysytemGenerator?返回错误Error evaluating ...
- swagger怎么扫描多个包_Swagger快速入门
- matlab反馈模型,—倒立摆状态反馈系统的建模及matlab仿真.docx
- IC/FPGA校招笔试题分析(四)再看Moore状态机实现序列检测器
- Xinlinx 7系列 FPGA 总览
- Ubuntu 16.04安装Wine版的迅雷+QQ(完美方案,终极解决方法)
- 【Python】 文件目录比较工具filecmp和difflib
- IOS、Android html5页面输入的表情符号变成了乱码”???“