标签:相关 lock 就是 open 并发 延时 软件 接收 文件的
# 进程锁 # 多个进程都操作一个数据时(下面指的是文件或数据库)、会存在数据安全问题,则需要加入锁 # 先说一个现象 # 买火车票 # 当我们手机软件买票时,发现有余票20张,但是点击订票后,告诉你票订光了 # 这是因为买票时,肯定是一个并发的过程,好多人同时来买票,并发的过程 # 当一个人订票后,我们后台肯定要修改票数,肯定是修改数据库中的剩余票数 # import json # import time # from multiprocessing import Process # # def show(): # ‘‘‘ # @funcation功能:模拟查询余票 # 显示余票 # :return: # ‘‘‘ # with open(‘ticket‘, mode=‘r‘) as f: # ticket文件中的内容是{"ticket":1}这个,模拟存储的票数 # dic = json.load(f) # print(‘余票:%s‘ % dic[‘ticket‘]) # # def buy_ticket(i): # ‘‘‘ # @funcation功能:模拟买票 # @param 表示谁来买票 # :return: # ‘‘‘ # with open(‘ticket‘) as f: # dic = json.load(f) # time.sleep(0.1) # 模拟网络延时 # # if dic[‘ticket‘] >= 1: # 有余票 # dic[‘ticket‘] -= 1 # 买一张票后,就减一张票 # print(‘\033[32m %d 买到票了\033[0m‘ % i) # else: # 没有余票了 # print(‘\033[31m %d 没买到票\033[0m‘ % i) # # time.sleep(0.1) # 模拟网络延时 # with open(‘ticket‘, mode=‘w‘) as f: # json.dumps(dic, f) # 将在内存中改写的余票数,写入到文件中,模拟写入数据库的过程 # # if __name__ == ‘__main__‘: # # 创建5个进程,都绑定的查询余票为子进程,模拟5个人查票,此时5个人都看到有1张票 # for i in range(5): # p = Process(target=show) # p.start() # # # 5个人看到有1张票后,则都去点击买票,此时5个人都显示买到票了,也可能多个人显示买票成功了,这是有问题的,因为只有1一张票,确多个人显示买成功了 # for i in range(5): # p = Process(target=buy_ticket, args=(i,)) # p.start() # 解决上面举的5个人查看余票都剩1张时,5个人都去点击买票,结果系统显示多个人买票成功的问题,可以用进程锁 # 上面的问题由于操作文件的相关代码被多个人(进程)操作, # 如果多个进程同时都去读那个文件,就会同时读到剩一张票,点击买票时,同样的多个进程同时都去加载那个文件中的剩余票数, # 多个进程都发现有余票1张,所以多个进程就认为有余票,就买了,然后将票数减1后,多个进程又同时将余票数写入到了文件中 # 解决上面的问题思路是,每个进程不能随便的就去读那个文件与写那个文件,而是需要拿到一个锁的钥匙后才能去操作那个文件,锁和钥匙只有一个 # 当一个进程需要操作那个文件后,则拿到那个钥匙,开了锁后,进入到抽象中的屋子中,则用钥匙关闭了门,然后开始操作文件。 # 此时如果有另一个进程也要进这个屋子的时候,则必须等待前面那个人操作完了文件后,将门打开并将钥匙归还,后面的人才能操作那个文件 # 这就是进程锁的概念 import json import time from multiprocessing import Process from multiprocessing import Lock # 导入进程锁模块 def show(): ‘‘‘ @funcation功能:模拟查询余票 显示余票 :return: ‘‘‘ with open(‘ticket‘, mode=‘r‘) as f: # ticket文件中的内容是{"ticket":1}这个,模拟存储的票数 dic = json.load(f) print(‘余票:%s‘ % dic[‘ticket‘]) def buy_ticket(i, lock): ‘‘‘ @funcation功能:模拟买票 @:param 表示谁来买票 @:param 接收锁对象的参数 @:return: ‘‘‘ lock.acquire() # 如果钥匙被归还了,则拿到钥匙开锁向下执行,如果钥匙没有被归还,则阻塞在这里,等待锁被归还。 上锁 with open(‘ticket‘) as f: dic = json.load(f) time.sleep(0.1) # 模拟网络延时 if dic[‘ticket‘] > 0: # 有余票 dic[‘ticket‘] -= 1 # 买一张票后,就减一张票 print(‘\033[32m %s 买到票了\033[0m‘ % i) else: # 没有余票了 print(‘\033[31m %s 没买到票\033[0m‘ % i) time.sleep(0.1) # 模拟网络延时 with open(‘ticket‘, mode=‘w‘) as f: json.dump(dic, f) # 将在内存中改写的余票数,写入到文件中,模拟写入数据库的过程 lock.release() # 归还钥匙 解锁 if __name__ == ‘__main__‘: # 创建5个进程,都绑定的查询余票为子进程,模拟5个人查票,此时5个人都看到有1张票 for i in range(5): p = Process(target=show) p.start() lock = Lock() # 得到一个锁对象 # 5个人看到有1张票后,则都去点击买票,此时每个进程都会先判断锁有没有被解开后再去买票,如果锁是上锁的则阻塞等待,先拿到钥匙的进程先买 for i in range(5): p = Process(target=buy_ticket, args=(i, lock)) # 将锁传进去 p.start()
标签:相关 lock 就是 open 并发 延时 软件 接收 文件的
原文地址:https://www.cnblogs.com/whylinux/p/9807267.html