1,锁机制(在异步进程的时候,多个子进程访问同一个资源时,会有数据混乱的情况)
from multiprocessing import Lock l = Lock() # 实例化一个锁的对象 l.acquire() # 拿走钥匙,锁门,不让其他人进屋(当有一个进程访问数据的时候.不允许其他进程访问) l.release() # 释放锁,还钥匙,开门,允许其他人进屋(当上一个进程访问完这个数据的时候,才会让下一个数据进行访问) from multiprocessing import Process, Lock,Value import time def get_money(num, l): # 取钱的进程 l.acquire() # 获取num数据的钥匙(把num的资源独自享有,不允许别的进程访问) for i in range(100): num.value -= 1 print("取钱:%s"%mun.value) time.sleep(0.1) l.release() # 等此子进程操作完毕后归还钥匙(是释放num的资源) def put_money(num, l): l.acquire() # 只有上一个子进程归还了钥匙(释放了公共资源)获取数据的钥匙 for i in range(100): num.value += 1 print("存钱:%s"%num.value) time.sleep(0.1) l.release() if __name__ == "__main__": num = Value("i", 100) l = Lock() # 实例化锁的对象(Lock其实是一个类) p = Process(target=get_money,args=(num,l)) # 实例化的对象然后开启子进程的函数时指定的,其他的没有,有且只有本函数一个 p.start() # 开启一个子进程 p1 = Process(target=put_money,args=(num,l)) p.join() # 等待这个子进程结束以后再执行主程序 p1.join() # 同理 time.sleep(0.1) print(num.value)
- 1.2>模仿网络购票
from multiprocessing import Process,Lock import time def check_ticket(i): with open("Spare_ticket") as f: content = f.read() print("第%s个人查余票了,还剩%s张"%(i,content)) time.sleep(0.1) def buy_ticket(i,l): l.acquire() # 所的机制是一次只能一个人购票(进程访问) with open("Spare_ticket") as f: content = int(f.read()) # 把数据库里的票数读出来 if content > 0: # 此时判断数据库里的余票还有多少张 content -= 1 print("第%s个人买到票了,还剩%s张票"%(i,content)) else: print("第%s个人没有买到票"%i) with open("Spare_ticket","w") as f: # 在执行完买票以后,把数据库里的数据更改掉 f.write(str(content)) time.sleep(0.1) l.release() # 每次一个进程使用完一个被锁着的资源的时候,就会释放这个资源 if __name__ == "__main__": l = Lock() # 实例化锁的对象 for i in range(100): p1 = Process(target=check_ticket,args=(i,)) p1.start() for i in range(100): p2= Process(target=buy_ticket,args=(i,l)) p2.start()
2,信号量机制
- l = Lock()...................实例化一个锁的对象
- l.acquire()..................获取锁的钥匙
- l.release()....................释放钥匙(有借有还,在借不难)
- l = Semaphore(4)..................实例化一个信号量的对象,括号里的参数是锁的几把钥匙,当什么都不写的时候,默认有一把钥匙,写了1也是有一把钥匙,当有四把钥匙的时候,就可以一次4个进程同时访问一个资源,无需前几个释放共有资源,其他有要访问共有资源的时候,就得等到这4个进程完事以后释放资源,在进行访问.
from multiprocessing import Process,Semaphore import time import random def func(i,s): s.acquire() # 跟锁是一样的,获取访问公共资源的权限(不过这一次获取的是5个权限) print("\033[32m这是第%s个人进入小黑屋\033[32m"%i) # 此时有5个进程同时访问共有的资源 time.sleep(random.randint(3,5)) print("这是第%s个人离开小黑屋"%i) # 此时只要有出去的进程就会有进来的进程,直到最后5个进程一起出去(有进有出,反复的一进一出) s.release() if __name__ == "__main__": s = Semaphore(5) # 实例化信号量的对象并配发5把钥匙(开5个进程可以访问共有资源的权限) for i in range(10): p = Process(target=func,args=(i,s)) p.start()
3,事件机制
from multiprocessing import Process,Event import time import random def tra(e): '''信号灯函数''' # e.set() # print('\033[32m 绿灯亮! \033[0m') while 1:# 红绿灯得一直亮着,要么是红灯要么是绿灯 if e.is_set():# True,代表绿灯亮,那么此时代表可以过车 time.sleep(5)# 所以在这让灯等5秒钟,这段时间让车过 print('\033[31m 红灯亮! \033[0m')# 绿灯亮了5秒后应该提示到红灯亮 e.clear()# 把is_set设置为False else: time.sleep(5)# 此时代表红灯亮了,此时应该红灯亮5秒,在此等5秒 print('\033[32m 绿灯亮! \033[0m')# 红的亮够5秒后,该绿灯亮了 e.set()# 将is_set设置为True def Car(i,e): e.wait()# 车等在红绿灯,此时要看是红灯还是绿灯,如果is_set为True就是绿灯,此时可以过车 print('第%s辆车过去了'%i) if __name__ == '__main__': e = Event() triff_light = Process(target=tra,args=(e,))# 信号灯的进程 triff_light.start() for i in range(50):# 描述50辆车的进程 if i % 3 == 0: time.sleep(2) car = Process(target=Car,args=(i+1,e,)) car.start()