多进程相关内容(IPC)
多进程相关内容
1.守护进程(daemon)
主进程创建守护进程: 1.守护进程会在主进程代码执行结束后就终止
2.守护进程内无法再开启子进程,否则抛出异常
注意:进程之间是相互独立的,主进程代码结束,守护进程随机终止
from multiprocessing import Process
def task():
print('son is running')
print('son is done')
if __name__ == '__main__':
p = Process(target = task)
p.daemon = True #要在p.start()前设置,设置p为守护进程
p.start()
print('father process')
2.进程同步
由于多道技术要求物理层面进程之间内存相互隔离,即数据不能共享.但是我们能共享同一套文件系统,所以访问同一个文件或同一个打印终端是没有任何问题的.
由于创建进程的速度不一,导致在共享文件就会产生数据错乱或打印错乱,我们引入了lock的概念,加锁:将并发变成串行,牺牲了运行效率,但避免了对硬件资源的竞争和保证了数据安全.
1.加锁
#模拟抢票
#json中存放字典的key格式必须以双引号注明
from multiprocessing import Process,Lock
import json
#查询余票信息
def search():
with open('db.json') as f:
data = json.load(f)
print('剩余票数:',data['count'])
#购买
def buy():
#由于网络延时,需重新获取余票信息
with open('db.json') as f:
data = json.load(f)
if data['count']>0:
data['count'] -= 1
with open('db.json','wt') as fw:
json.dump(data,fw)
print('抢票成功')
def task(mutex):
search()
mutex.acquire() #加锁
buy()
mutex.release() #解锁
if __name__ == '__main__':
mutex = Lock() #创建锁
for i in range(5):
p = Process(target=task,args=(mutex,))
p.start()
#加锁:保证多个进程修改同一块数据,同一时间只能有一个任务可以进行修改即串行的修改
#适用于: 1.共享数据较大,效率低
# 2.需要人为加锁
3.基于multiprocessing模块的IPC通信机制(推荐使用)
IPC:interface_process_communication(进程间通信),multiprocessing模块支持两种形式:队列和管道,这两种方式都是用来.
manager的使用
from multiprocessing import Process,Manager,Lock
def task(data,lock):
lock.acquire()
num = data[0]
data[0] = num - 1
lock.release()
print('son is done')
if __name__ == '__main__':
ls = [100]
m = Manager() #创建管理器
syncls = m.list(ls) #同步列表
lock = Lock()
ps = []
for i in range(10):
p = Process(target=task,args=(syncls,lock))
p.start()
ps.append(p)
for p in ps:p.join()
print(ls) #100
print(syncls) #90
队列和管道都是将数据存放于内存中的(即在运行时在内存中开辟一块共同存放数据的区域)
#队列原则:先进先出
from multiprocessing import Queue
q = Queue(5) #创建队列中,同时只能存在最多元素maxsize=5
q.put(1) #放入元素
q.put(1,block=True,timeout=1) #block阻塞,默认为true,timeout延时(当队列为空时,在该时间内放入元素
print(q.get(1) ) #取出队列元素
#栈,函数调用,原则:后进先出
def a():
b()
def b():
c()
def c():
print('c')
raise Exception
a()