互斥锁
将多个任务对修改共享数据的操作由并发变为“串行”
没有互斥锁的情况下
# json文件 {"count": 2} # 执行文件 import os import time import json import random from multiprocessing import Process def check(): with open("a.json","r",encoding="utf-8") as f: data_dic = json.load(f) time.sleep(random.random()) print('[%s] 在%s 查看了车票,车票还剩:%s' % (os.getpid(), time.strftime('%Y-%m-%d %X'), data_dic['count'])) def pay(): with open("a.json","r",encoding="utf-8") as f: data_dic = json.load(f) time.sleep(random.random()) if data_dic['count'] > 0: data_dic['count'] -= 1 time.sleep(random.random()) with open("a.json","w",encoding="utf-8") as f: json.dump(data_dic,f) print('[%s] 在%s 购买了车票' % (os.getpid(), time.strftime('%Y-%m-%d %X'))) else: print('[%s] 在%s 购票失败' % (os.getpid(), time.strftime('%Y-%m-%d %X'))) def buy_tickets(): check() pay() if __name__ == '__main__': for i in range(8): p = Process(target=buy_tickets) p.start()
发现,两张票被8个人购买
有互斥锁的情况下
# json 文件 {"count": 2} # 执行文件 import os import time import json import random from multiprocessing import Process, Lock def check(): with open("a.json", "r", encoding="utf-8") as f: data_dic = json.load(f) time.sleep(random.random()) print('[%s] 在%s 查看了车票,车票还剩:%s' % (os.getpid(), time.strftime('%Y-%m-%d %X'), data_dic['count'])) def pay(): with open("a.json", "r", encoding="utf-8") as f: data_dic = json.load(f) time.sleep(random.random()) if data_dic['count'] > 0: data_dic['count'] -= 1 time.sleep(random.random()) with open("a.json", "w", encoding="utf-8") as f: json.dump(data_dic, f) print('[%s] 在%s 购买了车票' % (os.getpid(), time.strftime('%Y-%m-%d %X'))) else: print('[%s] 在%s 购票失败' % (os.getpid(), time.strftime('%Y-%m-%d %X'))) def buy_tickets(lock): # 如果将锁加到这里,就将整个任务串行了 check() lock.acquire() # 该进程拿到锁,其余没有锁的进程等待 pay() lock.release() # 释放锁,其余等待进程竞争 ''' 或者使用with上下文管理 with lock: pay() ''' if __name__ == '__main__': mutex = Lock() # 获得锁对象 for i in range(8): p = Process(target=buy_tickets, args=(mutex,)) # p = Process(target=buy_tickets, kwargs={'lock': mutex}) p.start()
总结
1.多个任务并发的去操作共享数据会造成数据错乱,使用互斥锁,虽然使任务对共享数据的操作由并发变为“串行”,减低了效率,但是提高了数据的安全性
2.此方法的共享数据效率低(数据来自于硬盘) 并且需要自己去处理锁的问题
所以,为了解决第二个问题,就要寻求一种方法---->使多个进程共享一个内存空间中的共享数据,该方法可以替我们处理好锁的问题
IPC通信
管道与队列
扫描二维码关注公众号,回复: 3159524 查看本文章管道与队列将数据存放于内存中,而且队列是通过管道+锁实现的