Python中鎖Lock的類型舉例詳解
前言
在 Python 中,鎖(Lock) 是 threading
和 multiprocessing
模塊提供的同步機(jī)制,用于防止多個(gè)線程或進(jìn)程同時(shí)訪問(wèn)共享資源,從而避免數(shù)據(jù)競(jìng)爭(zhēng)和不一致問(wèn)題。
1. threading.Lock()(線程鎖)
用于在多線程環(huán)境下防止多個(gè)線程同時(shí)訪問(wèn)共享資源。
示例:多個(gè)線程訪問(wèn)共享變量
import threading import time counter = 0 # 共享變量 lock = threading.Lock() # 創(chuàng)建鎖 def worker(n): global counter with lock: # 獲取鎖 local_counter = counter time.sleep(0.1) # 模擬某些計(jì)算 counter = local_counter + n print(f"Thread {threading.current_thread().name} updated counter to {counter}") # 創(chuàng)建多個(gè)線程 threads = [threading.Thread(target=worker, args=(1,)) for _ in range(5)] # 啟動(dòng)線程 for t in threads: t.start() # 等待所有線程完成 for t in threads: t.join() print("Final counter value:", counter)
threading.Lock() 工作機(jī)制
lock.acquire()
: 獲取鎖(如果鎖已被占用,則阻塞)lock.release()
: 釋放鎖(讓其他線程可以獲?。?/li>with lock:
: 推薦的用法,with
語(yǔ)句確保鎖在退出代碼塊時(shí)自動(dòng)釋放,即使發(fā)生異常。
2. multiprocessing.Lock()(進(jìn)程鎖)
用于多進(jìn)程環(huán)境,防止多個(gè)進(jìn)程同時(shí)訪問(wèn)共享資源。
示例:多個(gè)進(jìn)程訪問(wèn)共享資源
import multiprocessing import time counter = multiprocessing.Value('i', 0) # 共享變量 lock = multiprocessing.Lock() # 進(jìn)程鎖 def worker(n): with lock: # 獲取鎖 local_counter = counter.value time.sleep(0.1) # 模擬某些計(jì)算 counter.value = local_counter + n print(f"Process {multiprocessing.current_process().name} updated counter to {counter.value}") # 創(chuàng)建多個(gè)進(jìn)程 processes = [multiprocessing.Process(target=worker, args=(1,)) for _ in range(5)] # 啟動(dòng)進(jìn)程 for p in processes: p.start() # 等待所有進(jìn)程完成 for p in processes: p.join() print("Final counter value:", counter.value)
multiprocessing.Lock() 工作機(jī)制
multiprocessing.Lock()
和threading.Lock()
接口相同,但作用于進(jìn)程間。with lock:
確保進(jìn)程互斥訪問(wèn)共享資源,防止數(shù)據(jù)不一致問(wèn)題。
3. RLock()(可重入鎖)
適用于遞歸調(diào)用或同一線程多次獲取鎖
import threading lock = threading.RLock() def recursive_function(n): if n <= 0: return with lock: # 允許同一線程多次獲取鎖 print(f"Acquired lock in recursion level {n}") recursive_function(n - 1) recursive_function(3)
普通 Lock 不能被同一線程多次 acquire(),但 RLock() 可以!
4. Semaphore()(信號(hào)量)
用于限制并發(fā)訪問(wèn)的線程/進(jìn)程數(shù)量(例如:數(shù)據(jù)庫(kù)連接池)。
import threading import time semaphore = threading.Semaphore(3) # 最多允許 3 個(gè)線程同時(shí)運(yùn)行 def worker(n): with semaphore: print(f"Thread {n} is running") time.sleep(2) print(f"Thread {n} finished") threads = [threading.Thread(target=worker, args=(i,)) for i in range(6)] for t in threads: t.start() for t in threads: t.join()
- 設(shè)定
Semaphore(3)
,最多 3 個(gè)線程能同時(shí)進(jìn)入。 - 常用于連接池、資源管理、并發(fā)限制等場(chǎng)景。
5. Condition()(條件變量)
用于線程間協(xié)調(diào),例如一個(gè)線程需要等另一個(gè)線程完成某個(gè)操作后才能繼續(xù)。
import threading condition = threading.Condition() shared_data = None def consumer(): global shared_data with condition: print("Consumer waiting...") condition.wait() # 等待生產(chǎn)者通知 print(f"Consumer received: {shared_data}") def producer(): global shared_data with condition: shared_data = "Data ready!" print("Producer produced data, notifying consumer...") condition.notify() # 通知消費(fèi)者 t1 = threading.Thread(target=consumer) t2 = threading.Thread(target=producer) t1.start() t2.start() t1.join() t2.join()
使用 Condition() 解決“生產(chǎn)者-消費(fèi)者”問(wèn)題。
6. Event()(事件)
線程間的簡(jiǎn)單信號(hào)通知機(jī)制(相當(dāng)于全局 flag)
import threading import time event = threading.Event() def worker(): print("Worker waiting for event...") event.wait() # 等待事件被 set print("Worker received event signal!") def set_event(): time.sleep(3) event.set() # 觸發(fā)事件 threading.Thread(target=worker).start() threading.Thread(target=set_event).start()
適用于:
- 線程間同步
- 控制多個(gè)線程的啟動(dòng)時(shí)機(jī)
總結(jié)
鎖類型 | 適用范圍 | 主要作用 |
---|---|---|
threading.Lock() | 線程間同步 | 互斥訪問(wèn)共享資源 |
multiprocessing.Lock() | 進(jìn)程間同步 | 互斥訪問(wèn)進(jìn)程共享資源 |
threading.RLock() | 遞歸調(diào)用 | 允許同一線程多次獲取鎖 |
threading.Semaphore(n) | 線程池/連接池 | 限制并發(fā)線程數(shù) |
threading.Condition() | 線程間通信 | 等待/通知機(jī)制(生產(chǎn)者-消費(fèi)者) |
threading.Event() | 線程間信號(hào) | 事件觸發(fā)機(jī)制 |
在多線程/多進(jìn)程編程中,正確使用 鎖 機(jī)制可以防止數(shù)據(jù)競(jìng)爭(zhēng)、保持?jǐn)?shù)據(jù)一致性,提高程序的可靠性和可維護(hù)性。
到此這篇關(guān)于Python中鎖Lock的類型舉例詳解的文章就介紹到這了,更多相關(guān)Python鎖Lock類型詳解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python3通過(guò)字符串訪問(wèn)和修改局部變量的方法實(shí)例
最近在看python中nonlocal和global的使用,參考網(wǎng)上的大作,寫(xiě)了點(diǎn)自己的心得,下面這篇文章主要給大家介紹了關(guān)于Python3通過(guò)字符串訪問(wèn)和修改局部變量的相關(guān)資料,需要的朋友可以參考下2022-04-04利用Python中SocketServer 實(shí)現(xiàn)客戶端與服務(wù)器間非阻塞通信
本文主要介紹了利用Python中SocketServer 實(shí)現(xiàn)客戶端與服務(wù)器間非阻塞通信示例代碼,具有很好的參考價(jià)值,需要的朋友一起來(lái)看下吧2016-12-12在Python 不同級(jí)目錄之間模塊的調(diào)用方法
今天小編就為大家分享一篇在Python 不同級(jí)目錄之間模塊的調(diào)用方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01Pandas替換及部分替換(replace)實(shí)現(xiàn)流程詳解
這篇文章主要介紹了Pandas替換及部分替換(replace)實(shí)現(xiàn)流程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10python 利用turtle模塊畫(huà)出沒(méi)有角的方格
今天小編就為大家分享一篇python 利用turtle模塊畫(huà)出沒(méi)有角的方格,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-11pytorch 計(jì)算Parameter和FLOP的操作
這篇文章主要介紹了pytorch 計(jì)算Parameter和FLOP的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-03-03python中內(nèi)置函數(shù)ord()返回字符串的ASCII數(shù)值實(shí)例詳解
ord()?函數(shù)是?chr()?函數(shù)(對(duì)于?8?位的?ASCII?字符串)的配對(duì)函數(shù),它以一個(gè)字符串(Unicode?字符)作為參數(shù),返回對(duì)應(yīng)的?ASCII?數(shù)值,或者?Unicode?數(shù)值,這篇文章主要介紹了python?中內(nèi)置函數(shù)ord()返回字符串的ASCII數(shù)值,需要的朋友可以參考下2022-07-07Pytho樹(shù)的直徑的計(jì)算實(shí)現(xiàn)
樹(shù)的直徑是樹(shù)中任意兩個(gè)節(jié)點(diǎn)之間最長(zhǎng)路徑的長(zhǎng)度,本文主要介紹了Pytho樹(shù)的直徑的計(jì)算實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2023-11-11OpenCV物體跟蹤樹(shù)莓派視覺(jué)小車實(shí)現(xiàn)過(guò)程學(xué)習(xí)
這篇文章主要介紹了OpenCV物體跟蹤樹(shù)莓派視覺(jué)小車的實(shí)現(xiàn)過(guò)程學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2021-10-10