進程同步(multiprocess.Lock)
鎖 —— multiprocess.Lock
進程之間數據不共享,但是共享同一套文件系統,所以訪問同一個文件,或同一個打印終端,是沒有問題的,
而共享帶來的是競爭,競爭帶來的結果就是錯亂,如何控制,就是加鎖處理
多進程模擬搶票實例
#文件db的內容為:{"count":1}
#注意一定要用雙引號,不然json無法識別
from multiprocessing import Process,Lock
import time,json,random
def search():
dic=json.load(open('db'))
print('\033[43m剩余票數%s\033[0m' %dic['count'])
def get():
dic=json.load(open('db'))
time.sleep(0.1) #模擬讀數據的網絡延遲
if dic['count'] >0:
dic['count']-=1
time.sleep(0.2) #模擬寫數據的網絡延遲
json.dump(dic,open('db','w'))
print('\033[43m購票成功\033[0m')
def task():
search()
get()
if __name__ == '__main__':
for i in range(100): #模擬並發100個客戶端搶票
p=Process(target=task)
p.start()
# 引發問題:數據寫入錯亂
互斥鎖保證數據安全
from multiprocessing import Process,Lock
import time,json,random
def search():
dic=json.load(open('db'))
print('\033[43m剩余票數%s\033[0m' %dic['count'])
def get():
dic=json.load(open('db'))
time.sleep(random.random()) # 模擬讀數據的網絡延遲
if dic['count'] >0:
dic['count']-=1
time.sleep(random.random()) # 模擬寫數據的網絡延遲
json.dump(dic,open('db','w'))
print('\033[32m購票成功\033[0m')
else:
print('\033[31m購票失敗\033[0m')
def task(lock):
search()
lock.acquire() # 將買票這一環節由並發變成了串行,犧牲了運行效率但是保證了數據的安全
get()
lock.release()
if __name__ == '__main__':
lock = Lock()
for i in range(100): # 模擬並發100個客戶端搶票
p=Process(target=task,args=(lock,))
p.start()
總結:加鎖可以保證多個進程修改同一塊數據時,同一時間只能有一個任務可以進行修改,即串行的修改,沒錯,速度是慢了,但犧牲了速度卻保證了數據安全。
問題:雖然可以用文件共享數據顯示進程間數據通信但問題是
- 效率低(共享數據基於文件,而文件是硬盤上的數據)
- 需要自己加鎖處理
針對上述問題,我們需要找到一種更加合理快捷的方式,那就是隊列和管道,下一小節介紹