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()
- View Code
- 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() 结束意味着
- # 主进程的代码运行完毕 --->(生产者运行完毕)+ 队列中的数据也被取干净了 ->消费者没有存在的意义
来源: https://www.cnblogs.com/luck-L/p/9299953.html