锁的概念以及 模拟抢票练习
一、重要概念
***** 锁: ### 应用场景:***** ### 多个进程需要操作同一份数据的时候,会产生数据不安全,应该使用锁,避免多个进程同时修改同一个文件! ### 为保证数据的安全,同一时刻同一段代码,只能由一个进程来执行这段代码。 ### 多进程中,只有去操作一些进程之间可以共享的数据资源的时候才需要加锁! ### 实现方法: ## acquire release ## 上下文管理:with lock: ### Lock ———— 是一个互斥锁!!!
二、代码
推荐利用“上下文管理”的方法加锁:
# -*- coding:utf-8 -*- import time import json from multiprocessing import Process,Lock def search_tickets(name): with open('tickets','r',encoding='utf-8')as f: dic = json.load(f) print('%s 查看余票还有:%s'%(name,dic['count'])) def buy_ticket(name): with open('tickets','r',encoding='utf-8')as f: dic = json.load(f) # 模拟读票的网络延迟 time.sleep(0.2) if dic['count'] >=1: dic['count'] -= 1 # 模拟买票的延迟 time.sleep(0.3) # 修改文件中的数据 with open('tickets','w',encoding='utf-8')as f: json.dump(dic,f) print('%s 成功购买了一张票!'%name) else: print('余票不足,%s 买票失败'%name) def buy(name,lock): # 查看可以同时进程 search_tickets(name) # 购票需要加锁 # 推荐上下文管理的方式 with lock: buy_ticket(name) if __name__ == '__main__': # 初始化一个锁对象 lock = Lock() # 开进程 name_lis = ['wanghw', 'whw', 'www', 'wahaha'] for name in name_lis: process_buy = Process(target=buy,args=(name,lock)) process_buy.start()
当然,在buy函数中,不用上下文管理的话,可以这样写:
def use(name,lock): # 查票可以是并发的 search_ticket(name) # 手动加锁 lock.acquire() buy_ticket(name) lock.release()
tickets文件中的内容如下(注意,要用json读取的话字典中字符串必须用双引号)
{"count": 2}
效果如下: