【Python】锁(Lock)的类型详解_python 锁
在 Python 中,锁(Lock) 是 threading
和 multiprocessing
模块提供的同步机制,用于防止多个线程或进程同时访问共享资源,从而避免数据竞争和不一致问题。
1. threading.Lock()
(线程锁)
用于在多线程环境下防止多个线程同时访问共享资源。
示例:多个线程访问共享变量
import threadingimport timecounter = 0 # 共享变量lock = threading.Lock() # 创建锁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}\")# 创建多个线程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()
工作机制
lock.acquire()
: 获取锁(如果锁已被占用,则阻塞)lock.release()
: 释放锁(让其他线程可以获取)with lock:
: 推荐的用法,with
语句确保锁在退出代码块时自动释放,即使发生异常。
2. multiprocessing.Lock()
(进程锁)
用于多进程环境,防止多个进程同时访问共享资源。
示例:多个进程访问共享资源
import multiprocessingimport timecounter = multiprocessing.Value(\'i\', 0) # 共享变量lock = multiprocessing.Lock() # 进程锁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}\")# 创建多个进程processes = [multiprocessing.Process(target=worker, args=(1,)) for _ in range(5)]# 启动进程for p in processes: p.start()# 等待所有进程完成for p in processes: p.join()print(\"Final counter value:\", counter.value)
multiprocessing.Lock()
工作机制
multiprocessing.Lock()
和threading.Lock()
接口相同,但作用于进程间。with lock:
确保进程互斥访问共享资源,防止数据不一致问题。
3. RLock()
(可重入锁)
适用于递归调用或同一线程多次获取锁
import threadinglock = 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()
(信号量)
用于限制并发访问的线程/进程数量(例如:数据库连接池)。
import threadingimport timesemaphore = threading.Semaphore(3) # 最多允许 3 个线程同时运行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()
- 设定
Semaphore(3)
,最多 3 个线程能同时进入。 - 常用于连接池、资源管理、并发限制等场景。
5. Condition()
(条件变量)
用于线程间协调,例如一个线程需要等另一个线程完成某个操作后才能继续。
import threadingcondition = threading.Condition()shared_data = Nonedef consumer(): global shared_data with condition: print(\"Consumer waiting...\") condition.wait() # 等待生产者通知 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()
解决“生产者-消费者”问题。
6. Event()
(事件)
线程间的简单信号通知机制(相当于全局 flag)
import threadingimport timeevent = 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() # 触发事件threading.Thread(target=worker).start()threading.Thread(target=set_event).start()
适用于:
- 线程间同步
- 控制多个线程的启动时机
总结
threading.Lock()
multiprocessing.Lock()
threading.RLock()
threading.Semaphore(n)
threading.Condition()
threading.Event()
在多线程/多进程编程中,正确使用 锁 机制可以防止数据竞争、保持数据一致性,提高程序的可靠性和可维护性。