Python中鎖Lock的類型舉例詳解
前言
在 Python 中,鎖(Lock) 是 threading 和 multiprocessing 模塊提供的同步機(jī)制,用于防止多個線程或進(jìn)程同時訪問共享資源,從而避免數(shù)據(jù)競爭和不一致問題。
1. threading.Lock()(線程鎖)
用于在多線程環(huá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) # 模擬某些計算
counter = local_counter + n
print(f"Thread {threading.current_thread().name} updated counter to {counter}")
# 創(chuàng)建多個線程
threads = [threading.Thread(target=worker, args=(1,)) for _ in range(5)]
# 啟動線程
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語句確保鎖在退出代碼塊時自動釋放,即使發(fā)生異常。
2. multiprocessing.Lock()(進(jìn)程鎖)
用于多進(jìn)程環(huán)境,防止多個進(jìn)程同時訪問共享資源。
示例:多個進(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) # 模擬某些計算
counter.value = local_counter + n
print(f"Process {multiprocessing.current_process().name} updated counter to {counter.value}")
# 創(chuàng)建多個進(jìn)程
processes = [multiprocessing.Process(target=worker, args=(1,)) for _ in range(5)]
# 啟動進(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()(信號量)
用于限制并發(fā)訪問的線程/進(jìn)程數(shù)量(例如:數(shù)據(jù)庫連接池)。
import threading
import time
semaphore = threading.Semaphore(3) # 最多允許 3 個線程同時運(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 個線程能同時進(jìn)入。 - 常用于連接池、資源管理、并發(fā)限制等場景。
5. Condition()(條件變量)
用于線程間協(xié)調(diào),例如一個線程需要等另一個線程完成某個操作后才能繼續(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() # 通知消費者
t1 = threading.Thread(target=consumer)
t2 = threading.Thread(target=producer)
t1.start()
t2.start()
t1.join()
t2.join()
使用 Condition() 解決“生產(chǎn)者-消費者”問題。
6. Event()(事件)
線程間的簡單信號通知機(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()
適用于:
- 線程間同步
- 控制多個線程的啟動時機(jī)
總結(jié)
| 鎖類型 | 適用范圍 | 主要作用 |
|---|---|---|
threading.Lock() | 線程間同步 | 互斥訪問共享資源 |
multiprocessing.Lock() | 進(jìn)程間同步 | 互斥訪問進(jìn)程共享資源 |
threading.RLock() | 遞歸調(diào)用 | 允許同一線程多次獲取鎖 |
threading.Semaphore(n) | 線程池/連接池 | 限制并發(fā)線程數(shù) |
threading.Condition() | 線程間通信 | 等待/通知機(jī)制(生產(chǎn)者-消費者) |
threading.Event() | 線程間信號 | 事件觸發(fā)機(jī)制 |
在多線程/多進(jìn)程編程中,正確使用 鎖 機(jī)制可以防止數(shù)據(jù)競爭、保持?jǐn)?shù)據(jù)一致性,提高程序的可靠性和可維護(hù)性。
到此這篇關(guān)于Python中鎖Lock的類型舉例詳解的文章就介紹到這了,更多相關(guān)Python鎖Lock類型詳解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
利用Python中SocketServer 實現(xiàn)客戶端與服務(wù)器間非阻塞通信
本文主要介紹了利用Python中SocketServer 實現(xiàn)客戶端與服務(wù)器間非阻塞通信示例代碼,具有很好的參考價值,需要的朋友一起來看下吧2016-12-12
Pandas替換及部分替換(replace)實現(xiàn)流程詳解
這篇文章主要介紹了Pandas替換及部分替換(replace)實現(xiàn)流程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-10-10
python中內(nèi)置函數(shù)ord()返回字符串的ASCII數(shù)值實例詳解
ord()?函數(shù)是?chr()?函數(shù)(對于?8?位的?ASCII?字符串)的配對函數(shù),它以一個字符串(Unicode?字符)作為參數(shù),返回對應(yīng)的?ASCII?數(shù)值,或者?Unicode?數(shù)值,這篇文章主要介紹了python?中內(nèi)置函數(shù)ord()返回字符串的ASCII數(shù)值,需要的朋友可以參考下2022-07-07
OpenCV物體跟蹤樹莓派視覺小車實現(xiàn)過程學(xué)習(xí)
這篇文章主要介紹了OpenCV物體跟蹤樹莓派視覺小車的實現(xiàn)過程學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2021-10-10

