并发编程的那些事(三)
1、锁机制
为了保护数据,有了锁机制,
from multiprocessing import Lock 导入锁模块
以存取钱为例
当你在存钱的时候,你的女朋友/男朋友正在取钱,此时你存10,他取10,由于数据没能及时更新,就有可能造成数据混乱。
一把钥匙配一把锁
包括12306购票系统也是应用了锁机制,保证在人多票少的情况下,不会出现多个人买到同一张票的情况。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from multiprocessing import Process, Lock import time def check_ticket(i): with open('remainder', 'r', encoding='utf-8')as f: count = int(f.read()) print('第%s个人查到%s张票' % (i, count)) # time.sleep(0.1) def buy_ticket(i, l): l.acquire() with open('remainder', 'r', encoding='utf-8')as f: count = int(f.read()) time.sleep(0.1) if count > 0: print('\033[31m第%s个人抢到了一张票\033[0m' % i) count -= 1 else: print('\033[33m第%s个人没有买到票\033[0m' % i) time.sleep(0.1) with open('remainder', 'w', encoding='utf-8')as f: f.write(str(count)) l.release() if __name__ == '__main__': l = Lock() for i in range(10): p1 = Process(target=check_ticket, args=(i + 1,)) p1.start() time.sleep(0.1) for i in range(10): p2 = Process(target=buy_ticket, args=(i + 1, l)) p2.start()
2、信号机制
3、事件机制
Event
e = Event()
e.is_set() 默认为False ,是一种标识
e.set() 可以将e.is_set()改为 True
e.clear() 可以将e.is_set()改为 False
e.wait() 判断is_set()的bool值,如果为True,则非阻塞,如果为False ,则阻塞。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from multiprocessing import Process, Event import time import random def traffic_light(e): while 1: if e.is_set(): time.sleep(5) print('\033[31m红灯了!\033[0m') e.clear() else: time.sleep(5) print('\033[32m绿灯了!\033[0m') e.set() def Car(i, e): e.wait() print('第%s辆车过去了' % i) if __name__ == '__main__': e = Event() p = Process(target=traffic_light, args=(e,)) p.start() for i in range(20): time.sleep(random.randint(1, 3)) p1 = Process(target=Car, args=(i + 1, e)) p1.start()