互斥锁:
本质上 是将并发的进程,变成“串行进程”(理论上的串行,从而保证数据安全)。牺牲效率,保证安全。
# -*- coding: utf-8 -*- """ 如下代码,没有加互斥锁,导致多个人都抢票成功,实际上只有一张票,出现该情况主要是开启进程的时候快速提交给操作系统,进程会先自行search 然后运行buy,buy过程一秒足够开启其他的几个进程,导致其他进程在buy过程中拿到数据不准确。还是之前的余票,并没有因为第一个抢到票人 购票成功, 而及时改变count 数量。多个进程同事进入buy操作,导致拿到的文件中的count 一样。 """ """ JSON文件 db.json----->内容: {"count":1} """ from multiprocessing import Process import json import random import time def search(name): with open('db.json', 'rt', encoding='utf-8') as f: dic = json.load(f) time.sleep(1) print('用户%s 查看余票 %s' % (name, dic['count'])) def buy(name): with open('db.json', 'rt', encoding='utf-8') as f: dic = json.load(f) if dic['count'] > 0: dic['count'] -= 1 time.sleep(random.randint(1, 3)) with open('db.json', 'wt', encoding='utf-8') as w: json.dump(dic, w) print('%s 抢票成功' % name) else: print('余票为0') def task(name): search(name) buy(name) if __name__ == '__main__': for i in range(1, 5): p = Process(target=task, args=('qzk%s' % i,)) p.start() # 用户qzk2 查看余票 1 # 用户qzk4 查看余票 1 # 用户qzk1 查看余票 1 # 用户qzk3 查看余票 1 # qzk2 抢票成功 # qzk3 抢票成功 # qzk4 抢票成功 # qzk1 抢票成功
二、加互斥锁
from multiprocessing import Process, Lock import json import random import time def search(name): with open('db.json', 'rt', encoding='utf-8') as f: dic = json.load(f) time.sleep(1) print('用户%s 查看余票 %s' % (name, dic['count'])) def buy(name): with open('db.json', 'rt', encoding='utf-8') as f: dic = json.load(f) if dic['count'] > 0: dic['count'] -= 1 time.sleep(random.randint(1, 3)) with open('db.json', 'wt', encoding='utf-8') as w: json.dump(dic, w) print('%s 抢票成功' % name) else: print('余票为0') def task(name, mutex): search(name) mutex.acquire() buy(name) mutex.release() # 另外一种写法 # with mutex: # buy(name) if __name__ == '__main__': mutex = Lock() for i in range(1, 5): p = Process(target=task, args=('qzk%s' % i, mutex)) p.start() # 用户qzk2 查看余票 1 # 用户qzk4 查看余票 1 # 用户qzk3 查看余票 1 # 用户qzk1 查看余票 1 # qzk2 抢票成功 # 余票为0 # 余票为0 # 余票为0