1. 程式人生 > 其它 >python-- 鎖Lock

python-- 鎖Lock

銀行存取錢

銀行存取錢是同時對一個數據操作,容易造成資料混亂,解決方法是加鎖

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個人買到票了