Python多进程实现原理
多进程
关键字
#p1.terminate() #主动杀死子进程
#p1.is_alive() #判断子进程是否存活
开启进程的俩种方式
#方式1:直接使用默认的Process类
#实验目的:查看进程起的时候是需要时间的,起的时间足够python把下面的代码运行完,
from multiprocessing import Process
import timedef task(name):print('1、%s is running' %name)time.sleep(5)print('2、%s is done' %name)
if __name__=='__main__':p=Process(target=task,args=('alex',)) #args后面使用的是一个元组的形式p.start() #起进程是需要时间的,起的时间足够python把下面的代码运行完# time.sleep(1) #在start()后面sleep(1)秒,会发现先执行第一个print.print('3、主')#方法2:自定义一个Process类
from multiprocessing import Process
import time
class MyProcess(Process):def __init__(self,name):super(MyProcess,self).__init__()self.name=name #自定义的功能def run(self): #自定义的Process类,必须要自定义一个run方法。print('1、%s is running' %self.name)time.sleep(3)print('2、%s is done' %self.name)
if __name__=='__main__':p=MyProcess('进程1')p.start() #相等于p.run(),执行自定义进程的方法
# time.sleep(1)
进程之间的内存空间是隔离的
#实验目的:使用pid验证进程和进程之间数据是相互隔离的
from multiprocessing import Process
import time,os
n=100
def task():global n #修改全局变量time.sleep(1)n=0print(n,os.getpid(),os.getppid())if __name__=='__main__':p=Process(target=task,)p.start()print(p.is_alive())p.join() #等待p这个进程运行完成才运行下面的代码print(p.is_alive()) #判断p这个进程是否存活print(n,os.getpid(),os.getppid())
# True
# 0 7480 2156 #n的值,子进程的pid,和子进程的父进程的pid
# False
# 100 2156 8312 #n的值,主进程的pid,父进程的pid(pycham的pid)
进程中的join方法使用
#实验目的,使用join方法实现并发执行,并且查看到起进程是需要耗时间的,并且很长
from multiprocessing import Process
import os,timedef task(n):print('1、%s is running' %n,os.getpid(),os.getppid())time.sleep(n)print('2、%s is done' %n,os.getpid(),os.getppid())if __name__=='__main__':p1=Process(target=task,args=(1,))p2=Process(target=task,args=(2,))p3=Process(target=task,args=(3,))stat=time.time()p_l=[p1,p2,p3]for p in p_l:p.start()for p in p_l:p.join()stop=time.time()print('主进程,%s'%str(stop-stat),os.getpid(),os.getppid())
# 1、1 is running 4680 6188
# 1、2 is running 9988 6188
# 1、3 is running 8564 6188
# 2、1 is done 4680 6188
# 2、2 is done 9988 6188
# 2、3 is done 8564 6188
# 主进程,3.3031890392303467 6188 8312 #3.3秒,由此可以看到起一个进程是需要耗时的,6188是主进程的pid,8312是pycharm的pid
进程对象的其它属性和方法
#主动杀死进程,杀死进程也是给系统发起一个信号,需要比较长的时间才能把进程杀死
from multiprocessing import Process
import time
import os
def task(n):print('1、%s is running' %n,os.getpid(),os.getppid())time.sleep(3)print('2、%s is done' %n,os.getpid(),os.getppid())if __name__=='__main__':stat=time.time()p1=Process(target=task,args=('lqx',))p1.start()time.sleep(1)print(p1.is_alive())p1.terminate() #给系统发一个信号,杀死子进程,这个是需要时间的,所有下面的判断,子进程还是存活的,如果休息一秒,会发现子进程已经没了time.sleep(1)print(p1.is_alive())p1.join()stop=time.time()print('3、主进程',stop-stat,os.getpid(),os.getppid())
守护进程的使用
主进程的代码运行完毕以后守护进程就没有意义存在了,会立马死掉
#守护进程:当子进程执行的任务在父进程代码运行完毕后就没有必要存在的必要了,那么该子进程需要设置为守护进程。
#实验目的:开启守护进程,是不能在守护进程中再次开启子进程的。
from multiprocessing import Process
import time,os
def bar():print('bar')
def task(name):# p=Process(target=bar,) #开启守护进程后不允许再次开启子进程# p.start()print('%s is runing' %name)time.sleep(2)print('%s is end' %name)
if __name__=='__main__':p=Process(target=task,args=('lqx',))p.daemon=True #守护进程开启必须在开启进程之前p.start()time.sleep(1)print('主进程')
# lqx is runing #在休息的1秒中的时候,守护进程启动,然后瞬间运行了第一条,然后sleep了,主进程运行完成了,程序结束
# 主进程#主进程代码运行完毕,守护进程就会结束
from multiprocessing import Process
from threading import Thread
import time
def foo():print(123)time.sleep(1)print('end')
def bar():print(456)time.sleep(2)print('end456')if __name__=='__main__':p=Process(target=foo)p2=Process(target=bar)p.daemon=Truep.start()p2.start()# time.sleep(0.5)print('main____')
# main____
# 456
# end456#没有打印123的原因是没有等到p1这个进程启动,代码就已经运行完成了,导致123没有出来,如果电脑运行过快,申请内存空间快,在P2.start()的时候,p1已经启动了,有可能就打印出来123,只要main__出现,123就不会出现了,p1(守护进程)立马会死掉
# 但是打印456,原因是:主进程需要等待非守护进程死掉后把pid给回收掉
进程的互斥锁
#实验目的:在修改数据文件的时候,如果并发执行,会导致数据文件修改紊乱的问题,因此使用互斥锁把并发改为串行,一个进程一个进程的去修改数据文件,保证数据的安全性
from multiprocessing import Process,Lock
import time,os,json,random
def search():time.sleep(random.randint(1,2))dic=json.load(open('db.txt','r',encoding='utf-8'))print('%s 查看余票为%s' %(os.getpid(),dic['count']))
def get():dic=json.load(open('db.txt','r',encoding='utf-8'))if dic['count'] >0:dic['count']-=1time.sleep(random.randint(0,1))json.dump(dic,open('db.txt','w',encoding='utf-8'))print('%s 购票成功!' %os.getpid())
def task(mutex):search()mutex.acquire()get()mutex.release()
if __name__=='__main__':mutex=Lock() #添加一个互斥锁,生成一个实例for i in range(10):p=Process(target=task,args=(mutex,))p.start()
进程实现队列
from multiprocessing import Queueq=Queue(3) #设置队列最大长度
q.put('first') #添加一个值到队列中
q.put(2)
q.put({'count':3})
# q.put('fourth') #如果添加值的个数超出队列长度,会发生队列阻塞。
# q.put('fourth',block=False) #q.put_nowait('fourth') #发生阻塞的时候主动抛出一个异常queue.Full
# q.put('fourth',block=True,timeout=3) #发生阻塞的时候等待3秒主动抛出一个异常queue.Fullprint(q.get()) #从队列中取出一个值
print(q.get())
print(q.get())
# print(q.get()) #如果队列为空,会发生队列阻塞
# print(q.get(block=False)) #如果队列为空,会主动抛出一个异常 queue.Empty
print(q.get(block=True,timeout=3)) #发生阻塞的时候等待3秒主动抛出一个异常queue.Empty
生产者和消费者模型
#实验目的:实现生产者生产东西,消费者去消费,生产多少消费多少
#生产者->队列->消费者
#生产者生产完成后,消费者去消费,会出现一种情况生产者p生产完成后就子进程就结束了,但是可能有多个,消费c在取值取到空的时候,会一直处于死循环中,一直卡在c.get()这一步
#解决方法一:
#在生产者生产完成后主进程q.put(None),有几个消费者就应该put几个空,然后当消费者取到空的时候,break掉循环
from multiprocessing import Process,JoinableQueue
import time,random
def producer(name,food,q):for i in range(3):res='%s%s' %(food,i)time.sleep(random.randint(1,2))q.put(res)print('厨师%s生产%s'%(name,res))def consumer(name,q):while True:res=q.get()if res is None:breaktime.sleep(random.randint(1,2))print('吃货%s吃掉了%s'%(name,res))if __name__=='__main__':q=JoinableQueue()q1=Process(target=producer,args=('lqx','水',q))q2=Process(target=producer,args=('yft','食物',q))c1=Process(target=consumer,args=('dog',q))c2=Process(target=consumer,args=('horse',q))c3=Process(target=consumer,args=('pig',q))q_l=[q1,q2,c1,c2,c3]for qn in q_l:qn.start()q1.join()q2.join()q.put(None)q.put(None)q.put(None)print('主')#解决方法2:守护进程在生产者消费者模型中的应用
from multiprocessing import Process,JoinableQueue
import time
import randomdef producer(name,food,q):for i in range(3):res='%s %s' %(name,food)time.sleep(random.randint(1,2))q.put(res)print('%s 生产出来 %s' %(name,food))
def consumer(name,q):while True:res=q.get()if res is None:breaktime.sleep(random.randint(1,2))print('%s 吃掉 %s' %(name,res))q.task_done() #消费者每取走一个值,给q.join()发送确认
if __name__=='__main__':q=JoinableQueue()p1=Process(target=producer,args=('lqx','骨头',q))p2=Process(target=producer,args=('yft','肉',q))c1=Process(target=consumer,args=('dog',q))c2=Process(target=consumer,args=('pig',q))c3=Process(target=consumer,args=('horse',q))p1.start()p2.start()c1.daemon=Truec2.daemon=Truec3.daemon=True #不添加消费者为守护进程,程序运行完成后,消费者c还是会循环取值,取到空值,卡在原地,把消费者设置为守护进程,等c1.start()c2.start()c3.start()p1.join()p2.join() #保障生产者把数据生产完q.join() #主进程可以暂停,等待队列结束print('主')
进程和线程之间的区别
- 线程间资源共享,进程间资源独立
Python多进程实现原理相关推荐
- python多进程_python语法:多进程
之前在一篇文章中写过,有关于Python线程的问题: 是枝裕和:内:用python多线程同时处理大量文件zhuanlan.zhihu.com 当然我的写的文章都是面对于一些初学者和python代码实 ...
- Python 多进程 multiprocessing 使用示例
参考:http://blog.csdn.net/qdx411324962/article/details/46810421 参考:http://www.lxway.com/4488626156.htm ...
- python多进程运行死机_python多进程假死
结论:python多进程间用Queue通信时,如果子进程操作Queue满了或者内容比较大的情况下,该子进程会阻塞等待取走Queue内容(如果Queue数据量比较少,不会等待),如果调用join,主进程 ...
- 以爬取知乎为例,进行python 多进程爬虫性能分析
以爬取知乎为例,进行python 多进程爬虫性能分析 如果对多进程multiproessing模块不熟悉,请先浏览 python 使用multiprocessing模块进行多进程爬虫 问题背景: 爬取 ...
- python多进程共享内存_python 进程间通信 共享内存
python多进程通信实例分析 python多进程通信实例分析操作系统会为每一个创建的进程分配一个独立的地址空间,不同进程的地址空间是完全隔离的,因此如果不加其他的措施,他们完全感觉不到彼此的存在.那 ...
- python多进程卡住_python多进程假死
结论:python多进程间用Queue通信时,如果子进程操作Queue满了或者内容比较大的情况下,该子进程会阻塞等待取走Queue内容(如果Queue数据量比较少,不会等待),如果调用join,主进程 ...
- python多进程详解
目录 python多进程 序.multiprocessing 一.Process process介绍 例1.1:创建函数并将其作为单个进程 例1.2:创建函数并将其作为多个进程 例1.3:将进程定义为 ...
- Python 多进程开发与多线程开发
我们先来了解什么是进程? 程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程.程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述文本:进程 ...
- python程序的原理_Python程序的执行原理(转)
1. 过程概述 Python先把代码(.py文件)编译成字节码,交给字节码虚拟机,然后虚拟机一条一条执行字节码指令,从而完成程序的执行. 2. 字节码 字节码在Python虚拟机程序里对应的是PyCo ...
- 取代Python多进程!伯克利开源分布式框架Ray
Ray由伯克利开源,是一个用于并行计算和分布式Python开发的开源项目.本文将介绍如何使用Ray轻松构建可从笔记本电脑扩展到大型集群的应用程序. 并行和分布式计算是现代应用程序的主要内容.我们需要利 ...
最新文章
- ecshop /api/client/api.php、/api/client/includes/lib_api.php SQL Injection Vul
- python【力扣LeetCode算法题库】20- 有效的括号(辅助栈)
- 响应式布局想法和实现
- 批处理 设置电脑最佳性能_批处理最佳做法
- 2003 cant connect to MySQL server on 'XXX.XXX.XXX.XXX'
- chrome用type=file获取图片路径并转base64字符串
- vs2013配置opencv2.4.9后出现找不到opencv_core249d.dll和opencv_highgui249d.dll问题
- 做数据分析还在死磕Excel?用这个简单工具,摆脱复杂函数和公式
- NOIP2016 复赛普及组第 1 题 买铅笔 方法一
- 没有一款趁手的数据监控软件?试一下NetData不,用了你就绝对离不开他!
- 虚拟服务器新建桌面池,VMware vSphere 服务器虚拟化之二十三 桌面虚拟化之建立手动虚拟桌面池...
- Google Chrome 将禁止“退格键”作为后退按钮使用
- 树的先序遍历递归的理解
- JZOJ 1714. 小x的三角形(triangles.pas/cpp)
- 数据分析师岗位需求数据分析
- mysql怎么创建外表_PostgreSQL使用MySQL外表的步骤详解(mysql_fdw)
- 给定经纬度定位某个城市
- 观自在菩萨,行深般若波罗蜜多时,照见五蕴皆空,度一切苦厄。舍利子,色不异空,空不异色,色即是空,空即是色,受想行识,亦复如是。舍利子,是诸法空相,不生不灭,不垢不净,不增不减。是故空中无色,无受想行识
- [QUANTAXIS量化分析]羊驼策略1
- Day13-寻觅踪迹