一:守护进程
1,守护进程介绍:
守护进程其实就是一个子进程
守护====》》伴随
守护进程会伴随主进程的代码运行完毕后而自动死掉
2,为何用守护模型,关键子就两个进程和守护
进程:当父进程需要将一个任务并发出去执行,需要将该任务放到一个子进程里面
守护:当该子进程内的代码在父进程代码运行完毕后就没有存在的意义,就应该将该子进程设置为守护进程,会在父进程代码结束后死掉。
3,如何使用
# from multiprocessing import Process
# import time,os
# 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('主')
4,#主进程代码运行完毕,守护进程就会结束
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-------")
可能输出的结果有不同的机器有不同的性能,新能不一样输出的结果也不一样
main-------
456
enn456
'''
2, '''
main-------
123
456
enn456
'''
3, '''
123
main-------
456
end456
'''
二:互斥锁
#互斥锁:可以将要执行任务的部分代码(只涉及带修改共享数据的代码)变成串行
#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'])
def get():
with open('db.txt','rt',encoding='utf-8') as f:
dic=json.load(f)
time.sleep(2)
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)
print('%s 购票成功' %os.getpid())
else:
print('%s 没有余票' %os.getpid())
def task(mutex):
# 查票
check()
#购票
mutex.acquire() # 互斥锁不能连续的acquire,必须是release以后才能重新acquire
get()
mutex.release()
#另外一种写法
# with mutex:
# get()
if __name__ == '__main__':
mutex=Lock()#创建锁
for i in range(10):
p=Process(target=task,args=(mutex,))
p.start()
# p.join()
三:IPC进程间通信,有两种方式
1,pipe
2,quenue:pipe+锁 #
#了解的
# q=Queue(3) #先进先出
# q.put('first',block=True,timeout=3)
# q.put({'k':'sencond'},block=True,timeout=3)
# q.put(['third',],block=True,timeout=3)
# print('===>')
# # q.put(4,block=True,timeout=3)
# print(q.get(block=True,timeout=3))
# print(q.get(block=True,timeout=3))
# print(q.get(block=True,timeout=3))
# print(q.get(block=True,timeout=3))
# q=Queue(3) #先进先出
# q.put('first',block=False,)
# q.put({'k':'sencond'},block=False,)
# q.put(['third',],block=False,)
# print('===>')
# # q.put(4,block=False,) # 队列满了直接抛出异常,不会阻塞
# print(q.get(block=False))
# print(q.get(block=False))
# print(q.get(block=False))
# print('get over')
# print(q.get(block=False))、
q=Queue(3) #先进先出
q.put_nowait('first') #q.put('first',block=False,)
q.put_nowait(2)
q.put_nowait(3)
# q.put_nowait(4)
print(q.get_nowait())
print(q.get_nowait())
print(q.get_nowait())
print(q.get_nowait())
四;生产者消费者模型
1,什么是生产者消费者模型:
生产者:比喻是程序中负责产生数据的任务
消费者:比喻的是程序中负责处理数据的任务
生产者——》共享的介质(队列)《——消费者
2,为何用
实现了生产者与消费者的解耦和,生产者可以不停的生产,消费者也可以不停的消费
从而平衡了生产者的上生产能力与消费者的消费能力,提升了程序整体运行的效率
3,何时用
当我们程序中存在明显的两类任务,一类负责产生数据,另一类负责处理数据,
此时就应该考虑使用生产者消费者模型来提升程序的效率
#举例:
# from multiprocessing import Queue,Process
# import time
# import os
# import 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('\033[45m%s 生产了 %s\033[0m' %(name,res))
# # q.put(None)
#
# def consumer(name,q):
# while True:
# #从队列里取走
# res=q.get()
# if res is None:break
# time.sleep(random.randint(1,3))
# print('\033[46m%s 吃了 %s\033[0m' %(name,res))
# if __name__ == '__main__':
# q=Queue()
# # 生产者们
# p1=Process(target=producer,args=('egon','包子',q,))
# p2=Process(target=producer,args=('杨军','泔水',q,))
# p3=Process(target=producer,args=('猴老师','翔',q,))
# # 消费者们
# c1=Process(target=consumer,args=('Alex',q,))
# c2=Process(target=consumer,args=('wupeiqidsb',q,))
# p1.start()
# p2.start()
# p3.start()
# c1.start()
# c2.start()
# p1.join()
# p2.join()
# p3.join()
# # 在p1\p2\p3都结束后,才应该往队列里放结束信号,有几个消费者就应该放几个None
# q.put(None)
# q.put(None)
# print('主')
#基于上面的程序进行优化
from multiprocessing import JoinableQueue,Process
import time
import os
import 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('\033[45m%s 生产了 %s\033[0m' %(name,res))
# q.put(None)
def consumer(name,q):
while True:
#从队列里取走
res=q.get()
if res is None:break
time.sleep(random.randint(1,3))
print('\033[46m%s 吃了 %s\033[0m' %(name,res))
q.task_done()
if __name__ == '__main__':
q=JoinableQueue()
# 生产者们
p1=Process(target=producer,args=('egon','包子',q,))
p2=Process(target=producer,args=('杨军','泔水',q,))
p3=Process(target=producer,args=('猴老师','翔',q,))
# 消费者们
c1=Process(target=consumer,args=('Alex',q,))
c2=Process(target=consumer,args=('wupeiqidsb',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() #等待队列被取干净
# q.join() 结束意味着
# 主进程的代码运行完毕--->(生产者运行完毕)+队列中的数据也被取干净了->消费者没有存在的意义
# print('主')