# 1.守护进程 1个进程b 他的守护进程a 在被守护进程b死亡的时候a已死亡
# 应用场景 在运行的qq过程中,开启了一个进程 用于下载文件 然而文件还没有下完qq就退出了 下载任务也应该跟随qq的退出而结束
# import time
# from multiprocessing import Process,Lock
#
#
#
# def task():
# print('妃子的一生')
# time.sleep(5)
# print('妃子凉凉了')
#
#
# if __name__ == '__main__':
# fz = Process(target=task)
# fz.daemon = True
# fz.start()
# print('皇帝登基了')
# time.sleep(2)
# print('当了10年皇帝')
# print('皇帝驾崩了')
# 2.互斥锁
# 当多个进程共享数据时候时,可能会造成数据错乱
# 1.使用join ,来让这些进程串行 但是这将造成无法并发,进程执行任务的顺序就固定了.
# 2.使用同一把锁 将需要共享的数据加锁 其他进程在访问数据的时候 那就必须等待当前进程使用完毕
# 锁的本质 就是一个bool类型的数据,在执行代码前会先判断这个值
#必须保证锁是同一把
#锁的实现原理伪代码:
#
# l=False
#
# def task4(lock):
# global l
# if l == False:
# l=True
# print('my name is 2')
# time.sleep(random.randint(1,2))
# print('my age is 19')
# l=False
#
#
#
#
#
#
#
#
# import random
# import time
#
#
# def task1(lock):
# lock.acquire() # 是一个阻塞函数 会等到别的进程释放锁时才能继续执行
# print('my name is 1')
# time.sleep(random.randint(1,2))
# print('my age is 18')
# lock.release()
#
# def task2(lock):
# lock.acquire()
# print('my name is 2')
# time.sleep(random.randint(1,2))
# print('my age is 19')
# lock.release()
#
# def task3(lock):
# lock.acquire()
# print('my name is 3')
# time.sleep(random.randint(1,2))
# print('my age is 20')
# lock.release()
#
# if __name__ == '__main__':
# lock=Lock()
# p1 = Process(target=task1,args=(lock,))
# p1.start()
# p2 = Process(target=task2,args=(lock,))
# p2.start()
# p3 = Process(target=task3,args=(lock,))
# p3.start()
#多个任务在共享一个数据 串行效率低 但是不会出现问题 并发效率高但是数据可能错乱
#模拟抢票
# import json,time,random
# from multiprocessing import Process,Lock
# def check_ticket(usr):
# with open("ticket.json",'r',encoding='utf-8') as f:
# dic =json.load(f)
# print('%s查看剩余票数%s'%(usr,dic['count']))
#
# def buy_ticket(usr):
# with open("ticket.json",'r',encoding='utf-8') as f:
# dic =json.load(f)
# if dic['count'] > 0:
# time.sleep(random.randint(1,2))
# dic['count']-=1
# with open('ticket.json','w',encoding='utf-8')as f2:
# json.dump(dic,f2)
# print('%s购买成功!'%usr)
#
#
# def task(usr,lock):
# check_ticket(usr)
# lock.acquire()
# buy_ticket(usr)
# lock.release()
# if __name__ == '__main__':
# lock = Lock()
#
#
# for i in range(5):
# p=Process(target=task,args=('用户%s'%i,lock))
# p.start() #首先全部并发查看票,然后买票的时候串行
#join 和锁的区别
# 1.join中的顺序是固定的 不公平
# 2.join是完全串行 而锁可以让部门代码串行,其他代码并发
# #Lock 和 Rlock的区别
# from multiprocessing import RLock
# # 1.在lock下 如果在执行代码前添加了2次lock.acquire() ,代码将无法执行
# lock = Lock()
# lock.acquire()
# lock.acquire()
# print('哈哈')
# lock.release()
# # 2.在Rlock模式下 如果在执行代码前添加无数次lock.acquire(),代码都可以运行. 表示重入锁 可以多次执行acquire
#
# lock = RLock()
# lock.acquire()
# lock.acquire()
# print('哈哈')
# lock.release()
#
#
#
#
#
# import time
#
# def task5(i):
# lock.acquire()
# lock.acquire()
# print(i)
# time.sleep(3)
# lock.release()
#
# if __name__ == '__main__':
# lock = RLock
# p1 = Process(target=task5,args=(1,lock))
# p1.start()
# p2 = Process(target=task5,args=(2,lock))
# p2.start()
# 当RLock存在2个进程进行竞争的时候 :
# 当只有一次acquire的时候也可以起到锁的作用;在代码中即为先打印了1之后过3秒再打印2
# 如果增加了一次acquire的执行次数而不添加release的次数,将会阻塞在第二个acquire, 即只打印出1,2不打印
# ipc进程间的通讯
# 三种方式:
# 1. 使用共享文件,过个进程同时读写一个文件
# i/o速度慢,传输大小不受限制
# 2.管道 是基于内存的速度快 但是是单向的 用起来麻烦
# 3.申请共享内存空间,多个进程可以共享这个内存区域,速度快 但是数据量不能太大
from multiprocessing import Manager,Process
def work(d):
d['count']-=1
if __name__ == '__main__':
# 开启了一个Manager共享内存
with Manager() as m:
dic = m.dict({'count':2}) #在这个空间中存储了一个字典
p_l = []
for i in range(2):
p=Process(target=work,args=(dic,))
p_l.append(p)
p.start() #就绪状态
for p in p_l:
p.join()
print(dic)
#相当于给子进程进行了串行
#队列: 不止用于进程之间的通讯 先进先出
from multiprocessing import Queue
q = Queue(1) #创建1个队列 最多可以存一个数据
q.put('a') #将a装入到队列中
q.put('b',False) #程序阻塞 put默认阻塞 当容器里面装满继续装就会阻塞住
# 2.put中如果第二个参数设置为False 表示不会阻塞无论容器是否塞满,都会强行塞,如果满了就抛异常
print(q.get()) #取出一个数据a
print(q.get()) #没有添加数据第二次取无数据就阻塞 默认阻塞
# 如果get中参数设为False 也是非阻塞,当取完了还要去取就报错
# 其中还有个参数timeout= 设置为3的时候表示 当阻塞状态下3秒还没有拿到数据会报错