守护进程,进程互斥锁,通信,生产者消费者模型
守护进程
1.守护进程
守护进程其实就是一个子进程
守护=》伴随
守护进程会伴随主进程的代码运行完毕后而死掉
2.为何守护进程
关键字就两个:
进程:
当父进程需要将一个任务并发出去执行,需要将该任务放到一个子进程里
守护:
当该子进程内的代码在父进程代码运行完毕后就没有存在的意义了,就应该将该子进程设置为守护进程,会在父进程代码结束后死掉
3.使用
p.daemon = True
互斥锁
# 互斥所:可以将要执行任务的部分代码(只涉及到修改共享数据的代码)变成串行
# 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()
IPC:
进程间的通信,有两种实现方式
1.pipe
2.queue:pipe + 锁
from multiprocessing import Queue
q = Queue(3) # 先进先出
注意:
1.队列占用的是内存空间
2.不应该往队列中放大数据,应该只存放数据量较小的消息
掌握的
q.put([1])
print(q.get())
了解的
q.put('first',block=True,timeout=3)
print(q.get(block=True,timeout=3))
q.put(4,block=False,) # 队列满了直接抛出异常,不会阻塞
q.put_nowait('first') #q.put('first',block=False,)
1.什么是生产者消费者模型
生产者:比喻的是程序中负责产生数据的任务
消费者:比喻的是程序中负责处理数据的任务
生产者 --》共享的介质(队列)《-- 消费者
2.为何用
实现了生产者与消费者的解耦和,生产者可以不停地生产,消费者也可以不停地消费
从而平衡了生产者的生产能力与消费者的消费能力,提升了程序整体运行的效率
什么时候用?
当我们的进程中存在明显的两类任务,一类负责产生数据,另外一类负责处理数据
当时就应该考虑使用生产者消费者模型来提升程序的效率
from multiprocessing import JoinableQueue, Process import time 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('%s 生产了 %s' % (name, res)) def consumer(name, q): while True: res = q.get() # 从队列取走 time.sleep(random.randint(1, 3)) print('%s 吃了 %s' % (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() 结束意味着 # 主进程的代码运行完毕--->(生产者运行完毕)+队列中的数据也被取干净了->消费者没有存在的意义