python-- 鎖Lock
阿新 • • 發佈:2021-07-14
銀行存取錢
銀行存取錢是同時對一個數據操作,容易造成資料混亂,解決方法是加鎖
from multiprocessing import Process from time import sleep def get_money(num): # 取錢 num -= 1 print('子程序:', num) if __name__ == '__main__': money_num = 100 p = Process(target=get_money, args=(money_num,)) p.start() p.join() # 等子程序結束 print(money_num)
結果:
子程序: 99 100
資料不共享原因導致的
共享記憶體
from multiprocessing import Process, Value from time import sleep def get_money(num): # 取錢 num.value -= 1 print('子程序:', num.value) if __name__ == '__main__': money_num = Value('i', 100) p = Process(target=get_money, args=(money_num,)) p.start() p.join()print(money_num.value)
結果:
子程序: 99 99
要共享記憶體有多個方法,這裡用Value,首先要匯入,money_num=Value('i',100)這句話的Value接收兩個引數,第一個是資料型別,第二個是這個型別的值,取值的時候要用x.value
銀行取錢問題
from multiprocessing import Process, Value from time import sleep def get_money(num): # 取錢 for i in range(100): num.value -= 1 sleep(0.01) def put_money(num): # 存取 for i in range(100): num.value += 1 sleep(0.01) if __name__ == '__main__': money_num = Value('i', 100) p = Process(target=get_money, args=(money_num,)) p.start() # 取錢 p1 = Process(target=put_money, args=(money_num,)) p1.start() # 存取 p1.join() p.join() print(money_num.value)
多執行幾次,有時候是100,有時候小於100,有時候大於100
鎖 Lock
from multiprocessing import Process, Lock l = Lock() # 例項化 l.acquire() # 加鎖。拿走鑰匙,鎖門,不讓其他人進屋 l.release() # 釋放鎖。還鑰匙,開門,允許其他人進屋
銀行存取錢加鎖
from multiprocessing import Process, Value, Lock from time import sleep def get_money(num, l): # 取錢 l.acquire() for i in range(100): num.value -= 1 sleep(0.01) l.release() def put_money(num, l): # 存取 for i in range(100): l.acquire() # 建議小範圍的加鎖 num.value += 1 l.release() sleep(0.01) if __name__ == '__main__': l = Lock() # 例項化鎖 money_num = Value('i', 100) p = Process(target=get_money, args=(money_num, l)) p.start() # 取錢 p1 = Process(target=put_money, args=(money_num, l)) p1.start() # 存取 p1.join() p.join() print(money_num.value)
不管操作多少次都是100
遇見l.acquire()給資料加個鎖,別的程序就不能操作這個資料了,直到l.release()之後其他的程序才可以操作鎖,建議小範圍內加鎖
模擬 12306 強票
from multiprocessing import Process, Lock import time def check(i): with open('餘票') as f: con = f.read() print('第%s個人查到餘票還剩%s張' % (i, con)) def buy_ticket(i, l): l.acquire() # 拿鑰匙,鎖門 with open('餘票') as f: con = int(f.read()) time.sleep(0.1) if con > 0: print('\033[31m 第%s個人買到票了\033[0m' % i) con -= 1 else: print('\033[32m 第%s個人沒有買到票\033[0m' % i) time.sleep(0.1) # 是指 買完票後,把餘票數量重寫寫入資料庫的時間延遲 with open('餘票', 'w') as f: f.write(str(con)) l.release() # 還鑰匙,開門 if __name__ == '__main__': l = Lock() for i in range(10): p_ch = Process(target=check, args=(i + 1,)) p_ch.start() for i in range(10): p_buy = Process(target=buy_ticket, args=(i + 1, l)) p_buy.start()
新建一個 “餘票” 的檔案,寫個12
執行結果
第1個人查到餘票還剩12張
第2個人查到餘票還剩12張
第3個人查到餘票還剩12張
第4個人查到餘票還剩12張
第5個人查到餘票還剩12張
第6個人查到餘票還剩12張
第7個人查到餘票還剩12張
第8個人查到餘票還剩12張
第9個人查到餘票還剩12張
第10個人查到餘票還剩12張
第1個人買到票了
第2個人買到票了
第3個人買到票了
第4個人買到票了
第5個人買到票了
第6個人買到票了
第7個人買到票了
第8個人買到票了
第9個人買到票了
第10個人買到票了