简单抢票模拟:开启多个进程对一个文件进行读写,错误版:
import json
import os
from multiprocessing import Process
import time
import random
def select():
time.sleep(random.randint(0, 2))
with open('w.txt',encoding='utf8') as f1:
dic = json.load(f1)
print(f"当前票数剩余{dic['aaa']}张")
if dic['aaa'] > 0:
pay()
else:
print('没有余票,暂时不能购买')
def pay():
with open('w.txt',encoding='utf8') as f2:
dic = json.load(f2)
dic['aaa'] -= 1
time.sleep(random.randint(0, 3))
with open('w.txt','w',encoding='utf8') as f2:
json.dump(dic,f2)
print(f'{os.getpid()}已经购买成功')
def task():
select()
if __name__ == '__main__':
for i in range(6):
p = Process(target=task)
p.start()
这种程序多个进程同时对一个文件进行读写,本来是剩余1张票,多个进程看到的都是1张票,都能进程购买,但是实际上只有一个人能进行购买。
所以必须购买必须得串行购买才行。
给购买环节加锁,正确版:
import json
import os
from multiprocessing import Process
from multiprocessing import Lock
import time
import random
def select():
time.sleep(random.randint(0, 2))
with open('w.txt',encoding='utf8') as f1:
dic = json.load(f1)
print(f"当前票数剩余{dic['aaa']}张")
def pay():
with open('w.txt', encoding='utf8') as f2:
dic = json.load(f2)
if dic['aaa'] > 0:
dic['aaa'] -= 1
time.sleep(random.randint(0, 3))
with open('w.txt', 'w', encoding='utf8') as f2:
json.dump(dic, f2)
print(f'{os.getpid()}已经购买成功')
else:
print('没有余票,暂时不能购买')
def task(lock):
select()
lock.acquire() #加锁
pay()
lock.release() #释放锁
if __name__ == '__main__':
mutex = Lock()
for i in range(6):
p = Process(target=task,args=(mutex,))
p.start()
基于文件得进程通信,虽然多进程在内存中是相互隔离的,但是多个进程都可以对文件进行操作。不过这样相对来说效率低,然后就是业务复杂的时候容易出现死锁。