Python中鎖Lock的類型舉例詳解
前言
在 Python 中,鎖(Lock) 是 threading 和 multiprocessing 模塊提供的同步機(jī)制,用于防止多個(gè)線程或進(jìn)程同時(shí)訪問共享資源,從而避免數(shù)據(jù)競(jìng)爭(zhēng)和不一致問題。
1. threading.Lock()(線程鎖)
用于在多線程環(huán)境下防止多個(gè)線程同時(shí)訪問共享資源。
示例:多個(gè)線程訪問共享變量
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(): 釋放鎖(讓其他線程可以獲取)with lock:: 推薦的用法,with語句確保鎖在退出代碼塊時(shí)自動(dòng)釋放,即使發(fā)生異常。
2. multiprocessing.Lock()(進(jìn)程鎖)
用于多進(jìn)程環(huán)境,防止多個(gè)進(jìn)程同時(shí)訪問共享資源。
示例:多個(gè)進(jì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)程互斥訪問共享資源,防止數(shù)據(jù)不一致問題。
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ā)訪問的線程/進(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)者”問題。
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() | 線程間同步 | 互斥訪問共享資源 |
multiprocessing.Lock() | 進(jì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)文章
python獲取時(shí)間戳的實(shí)現(xiàn)示例(10位和13位)
這篇文章主要介紹了python獲取時(shí)間戳的實(shí)現(xiàn)示例(10位和13位),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
Python中Scipy庫(kù)在信號(hào)處理中的應(yīng)用詳解
信號(hào)處理作為數(shù)字信號(hào)處理領(lǐng)域的關(guān)鍵技術(shù),涵蓋了從信號(hào)獲取、傳輸、存儲(chǔ)到最終應(yīng)用的一系列處理步驟,在這篇博客中,我們將深入探討Python中Scipy庫(kù)在信號(hào)處理領(lǐng)域的應(yīng)用,需要的朋友可以參考下2023-12-12
Python通用驗(yàn)證碼識(shí)別OCR庫(kù)ddddocr的安裝使用教程
dddd_ocr是一個(gè)用于識(shí)別驗(yàn)證碼的開源庫(kù),又名帶帶弟弟ocr,下面這篇文章主要給大家介紹了關(guān)于Python通用驗(yàn)證碼識(shí)別OCR庫(kù)ddddocr的安裝使用教程,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07
Python添加時(shí)間軸以實(shí)現(xiàn)動(dòng)態(tài)繪圖詳解
這篇文章主要為大家詳細(xì)介紹了Python如何添加時(shí)間軸以實(shí)現(xiàn)動(dòng)態(tài)繪圖,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以參考一下2023-09-09
Python數(shù)據(jù)自動(dòng)化處理之?dāng)?shù)據(jù)清洗和報(bào)表生成詳解
這篇文章主要介紹了一個(gè)全自動(dòng)數(shù)據(jù)處理流水線的Python實(shí)現(xiàn)方案,幫助用戶解決日常數(shù)據(jù)處理痛點(diǎn),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下2026-03-03
python實(shí)現(xiàn)文件+參數(shù)發(fā)送request的實(shí)例代碼
這篇文章主要介紹了python實(shí)現(xiàn)文件+參數(shù)發(fā)送request的實(shí)例代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01
python通過urllib2爬網(wǎng)頁上種子下載示例
這篇文章主要介紹了通過urllib2、re模塊抓種子下載的示例,需要的朋友可以參考下2014-02-02

