守护进程
'''
1、守护进程
守护进程其实就是一个“子进程”
守护=》伴随
守护进程会伴随主进程的代码运行完毕后而死掉
2、为何用守护进程
关键字就两个:
进程:
当父进程需要将一个任务并发出去执行,需要将该任务放到一个子进程里
守护:
当该子进程内的代码在父进程代码运行完毕后就没有存在的意义了,就应该
将该子进程设置为守护进程,会在父进程代码结束后死掉
'''
from multiprocessing import Process import time def task(name): print("%s is running" %name) time.sleep(3) if __name__ == '__main__': p1 = Process(target=task,args=("守护进程",)) p2 = Process(target=task,args=("正常的子进程",)) p1.daemon= True#要放在p.start()之前,并且只要是守护进程都不会打印内容 p1.start() p2.start() print("主")#主进程结束之后,守护进程就已经结束
from multiprocessing import Process import time def foo(): print(123) time.sleep(1) print("end123") def bar(): print(456) time.sleep(3) print("end456") if __name__ == '__main__': p1=Process(target=foo) p2=Process(target=bar) p1.daemon=True p1.start() p2.start() print("main-------")
互斥锁
#互斥锁:可以将要执行任务的部分代码(只涉及到修改共享数据的代码)变成串行
#join:是要执行任务的所有代码整体串行
from multiprocessing import Process,Lock import json import os import time import random def check(): time.sleep(1)#模拟网路延迟 with open("db.txt","rt",encoding="utf-8") as f: dic = json.load(f) print("%s 查看到生于票数[%s]" %(os.getpid(),dic["count"])) #显示哪个id看到的票数 def get(): with open("db.txt","rt",encoding="utf-8") as f: dic = json.load(f) time.sleep(random.randint(1,3)) if dic["count"] > 0: #有票 dic["count"]-=1 time.sleep(random.randint(1,3)) with open("db.txt","wt",encoding="utf-8") as f: json.dump(dic,f)#以json模块进行存储 print("%s 购票成功" %os.getpid()) else: print("%s 没有余票" %os.getpid()) def task(mutex): #查票 check() #购票 mutex.acquire()#互斥锁不能连续锁acquire(获得上锁),必须是release(放解锁)以后 # 才能重新acquire,锁需要在想要上锁的函数正上方输入mutex.acquire(),然后再想要 # 解锁的位置输入mutex.release() # 简洁写法再函数上方with mutex: # with mutex: # get()#只锁了get,其他并没有锁 # check()#购票后的查看都是随机时间查看,没有规定必须谁先出来谁可以查看 # check() # check() get() mutex.release() if __name__ == '__main__': mutex = Lock()#互斥锁要在main下方 for i in range(10): p=Process(target = task,args = (mutex,)) p.start()
IPC进程间通信,两种方式
IPC:进程间通信,有两种实现方式
1、pipe:
2、queue:pipe+锁
# q=Queue(3)#设置队列最大存放数,先进先出 # #注意: # #1、队列占用的是内存空间 # #2、不应该往队列中放大数据,应该只存放数据量较小的信息 # #掌握的 # q.put('first') # q.put({'k':'sencond'}) # q.put(['third',]) # #当超过队列最大存放数时会堵塞,默认会进入等待,等待前面的被取走,然后再进 # q.put(4) # # print(q.get()) # print(q.get()) # print(q.get()) # #超过队列最大取出数时会堵塞,默认会进入等待,等待前面有新放入,然后取出 # print(q.get()) # print(q.get(block=True,timeout=4))
# q=Queue(3) # q.put('first') # q.put({'k':'sencond'}) # q.put(['third',]) # #默认的block为True,如果将block改为False,造成队列堵塞时会直接报错, # # 如果block为True,timeout为计时秒数,超过等待秒数会报错 # q.put(4,block=True,timeout=3) # # print(q.get()) # print(q.get()) # print(q.get()) q=Queue(3) q.put('first') q.put({'k':'sencond'}) q.put(['third',]) print(q.get()) print(q.get()) print(q.get()) #默认的block为True,如果将block改为False,队列中没东西取出会自动报错, # 如果block为True,timeout为计时秒数,超过等待秒数会报错 print(q.get(block=True,timeout=None))
生产者消费者模型:
'''
1 什么是生产者消费者模型
生产者:比喻的是程序中负责产生数据的任务
消费者:比喻的是程序中负责处理数据的任务
生产者->共享的介质(队列)<-消费者
2 为何用
实现了生产者与消费者的解耦和,生产者可以不停地生产,消费者也可以不停地消费
从而平衡了生产者的生产能力与消费者消费能力,提升了程序整体运行的效率
什么时候用?
当我们的程序中存在明显的两类任务,一类负责产生数据,另外一类负责处理数据
此时就应该考虑使用生产者消费者模型来提升程序的效率
'''
from multiprocessing import Queue,Process import time,os,random def producer(q): for i in range(10):#循环每次的数值 res="包子%s" %i time.sleep(random.randint(1,3)) q.put(res)#将制作好的东西放入到队列中 print("%s 生产了%s" %(os.getpid(),res)) q.put(None) def consumer(q): while True: res=q.get()#循环从队列中取出内容 if res is None:break time.sleep(random.randint(1,3)) print("%s 吃了 %s" %(os.getpid(),res)) if __name__ == '__main__': q=Queue() p1=Process(target=producer,args=(q,)) c1=Process(target=consumer,args=(q,)) p1.start() c1.start() print("主")
from multiprocessing import Queue,Process import time,random,os def produce(name,food,q): for i in range(3): res = "%s %s" %(food,i) time.sleep(random.randint(1,3)) q.put(res) print("%s 生产了 %s" %(name,food)) def consumer(name,q): while True: res = q.get() if res is None:break time.sleep(random.randint(1,3)) print("%s 吃了 %s" %(name,res)) if __name__ == '__main__': q=Queue() p1 = Process(target=produce,args=("egon","包子",q)) p2 = Process(target=produce,args=("hm","汉堡",q)) p3 = Process(target=produce,args=("张飞","鹿腿",q)) c1 = Process(target=consumer,args=("fxc",q)) c2 = Process(target=consumer,args=("cc",q)) p1.start() p2.start() p3.start() c1.start() c2.start() p1.join() p2.join() p3.join() # 在p1p2p3都结束后,才应该往队列里放结束信号,有几个消费者就应该放几个None q.put(None) q.put(None) print("主")
from multiprocessing import JoinableQueue,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,3)) q.put(res) print("%s 生产了 %s" %(name,res)) def consumer(name,q): while True: res = q.get() if res is None:break time.sleep(random.randint(1,3)) print("%s 吃了 %s" %(name,res)) q.task_done()#队列里面每取出一个就-1 if __name__ == '__main__': q=JoinableQueue() p1=Process(target=producer,args=("egon","包子",q)) p2=Process(target=producer,args=("hm","汉堡",q)) p3=Process(target=producer,args=("张飞","鹿腿",q)) c1=Process(target=consumer,args=("fxc",q)) c2=Process(target=consumer,args=("cc",q)) c1.daemon=True c2.daemon=True p1.start() p2.start() p3.start() c1.start() c2.start() p1.join() p2.join() p3.join() q.join()#等待列队内被取干净 # 主进程的代码运行完毕--->(生产者运行完毕)+队列中的数据也被取干净了->消费者没有存在的意义