1 守护进程:
主进程 创建 守护进程 辅助主进程的运行
设置进程的 daemon属性 p1.daemon=True
1 守护进程会在主进程代码执行结束后就终止;
2 守护进程内无法再开启子进程,否则抛出异常;
AssertionError: daemonic processes are not allowed to have children
注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即终止
from multiprocessing import Process import time def work(n): print('---start') time.sleep(0.5) print('---end') def work2(): print('主人死了') time.sleep(6) print(' 我也不活了!') if __name__=='__main__': p1=Process(target=work,args=(2,)) p2=Process(target=work2) p2.daemon=True # 修改 daemon属性 守护进程 不能再开子进程 p1.start() p2.start() time.sleep(5) print('主') # 主进程结束---子进程(辅助进程)马上结束
2 同步锁 互斥锁
进程之间数据通信----需要共享数据 ======多进程 共享数据===== 进程 之间 用 共享空间(争抢) ---- 硬盘 文件 修改共享数据---串行 ---保证数据安全 其他操作---并发
lock 可以锁住一部分 内容 ===== 把一部分并发 变为串行
# 模拟购票 from multiprocessing import Process,Lock import os import time import json import random def search(n): # 查找---并发 dic=json.load(open('db.txt')) print('<%s> 查到的剩余票数 [%s] '%(n,dic['count']))
def get(n): # 修改操作---串行 dic=json.load(open('db.txt')) if dic['count']>0: dic['count']-=1 time.sleep(random.randint(1,3)) json.dump(dic,open('db.txt','w')) print('<%s> 购票成功'%(n)) def task(n,lock): search(n) lock.acquire() # 加锁 get(n) lock.release() # 解锁 # with lock: # get(n) # lock 支持上下文管理 if __name__=='__main__': lock=Lock() for i in range(30): p=Process(target=task,args=(i,lock)) p.start()
3 IPC机制: ---- 内存数据的通信
内存空间 ---- 共享的内存 (硬盘速度慢) ---进程之间的数据通信---
共享----竞争---无序---不安全 IPC机制 (进程间的通信) ---- (内存空间的数据通信) ----实现方法 队列 管道 数据安全---lock 锁 队列 (管道+锁)---基于IPC编程 管道------------基于IPC编程
队列:
=== 队列 ===== from multiprocessing import Queue q=Queue(3) # 只能放三次数据 q.put('bb') q.put((3,1,2,5)) q.put({'a':1}) # q是队列对象 --- q 放在内存中 # q.get_nowait(11111) 不等 满了就会报错 print(q.get()) print(q.get()) print(q.get()) # print(q.get_nowait()) 不等 没有就会 报错
4 生产者 消费者 模型:
涉及到两个进程之间的通信---内存数据的交互(管道)---安全(锁) ==== 队列(管道+锁) 生产者 消费者 ===== 通过 共享空间 (解耦合) ----队列
生产者消费者模型:
1 程序中有两类角色
一类负责生产数据(生产者) 一类负责处理数据(消费者)
2 引入生产者消费者模型的目的:
平衡生产者 与 消费者之间的 速度差
3 如何实现:
生产者---队列----消费者 (解耦合)
# 生产者 消费者 模型
from multiprocessing import Queue,Process import time,random def producer(name,q): for i in range(10): time.sleep(0.2) res='%s 制作的第%s包子'%(name,i) q.put(res) # q.put(None)
def consumer(name,q): while True: res=q.get() if not res:break print('%s 吃了 %s'%(name,res)) if __name__=='__main__':
q=Queue() p=Process(target=producer,args=('egon',q)) #共享的管道 q p2=Process(target=consumer,args=('alex',q)) #共享的管道 q p.start() p2.start() p.join() # 等待p进程结束 q.put(None)