多進程操作-進程鎖multiprocess.Lock的使用


多進程操作-進程鎖multiprocess.Lock的使用

​ 通過之前的Process模塊的學習,我們實現了並發編程,雖然更加充分地利用了IO資源,但是也有缺陷:當多個進程共用一份數據資源的時候,就會引發數據數據安全或者順序混亂的問題。

​ 如上問題,我們就引入了進程鎖來維護執行順序

​ 以模擬搶票為例,看看數據安全的重要性:

from  multiprocessing import Process,Lock
import json,time,os

# 獲取剩余票數
def search():
    time.sleep(1) # 模擬網絡io(網絡延遲)
    with open('db.txt','rt',encoding='utf-8') as fr:
        res = json.load(fr)
        # print(res)
        print(f"還剩{res['count']}")

def get():
    with open('db.txt','rt',encoding='utf-8') as fr:
        res = json.load(fr)

    time.sleep(1)  # 模擬網絡io(網絡延遲)
    if res['count'] > 0 :
        res['count'] -= 1
        with open('db.txt','wt',encoding='utf-8') as fw:
            json.dump(res,fw)
            print(f'進程{os.getpid()} 搶票成功')
        time.sleep(1)   # 模擬網絡io(網絡延遲)

    else:
        print('票已經售空了!!!')

def func(lock):
    search()

    # 鎖住
    lock.acquire()
    get()
    lock.release()


if __name__ == '__main__':
    lock = Lock()  # 寫在主進程是為了讓子進程拿到一把鎖
    for i in range(10):
        p = Process(target=func,args=(lock,))
        p.start()
        # p.join()

# 進程鎖 是把鎖住的代碼變成了串行
# join 是把所有非子進程變成了串行

# 為了保證數據的安全,串行犧牲掉了效率

加鎖可以保證多個進程修改同一塊數據時,同一時間只能有一個任務可以進行修改,即串行的修改,沒錯,速度是慢了,但犧牲了速度卻保證了數據安全。

雖然可以用文件共享數據實現進程間通信,但問題是:

  1. 效率低(共享數據基於文件,而文件是硬盤上的數據)
  2. 需要自己加鎖處理

因此我們最好找尋一種解決方案能夠兼顧:

  1. 效率高(多個進程共享一塊內存的數據)
  2. 幫我們處理好鎖問題。這就是mutiprocessing模塊為我們提供的基於消息的IPC通信機制:隊列和管道。

隊列和管道都是將數據存放於內存中,隊列又是基於(管道+鎖)實現的,可以讓我們從復雜的鎖問題中解脫出來,我們應該盡量避免使用共享數據,盡可能使用消息傳遞和隊列,避免處理復雜的同步和鎖問題,而且在進程數目增多時,往往可以獲得更好的可獲展性。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM