前言
在 python 中,锁(lock) 是 threading 和 multiprocessing 模块提供的同步机制,用于防止多个线程或进程同时访问共享资源,从而避免数据竞争和不一致问题。
1. threading.lock()(线程锁)
用于在多线程环境下防止多个线程同时访问共享资源。
示例:多个线程访问共享变量
import threading
import time
counter = 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 multiprocessing
import time
counter = 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 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()(信号量)
用于限制并发访问的线程/进程数量(例如:数据库连接池)。
import threading
import time
semaphore = 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 threading
condition = threading.condition()
shared_data = none
def 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 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() # 触发事件
threading.thread(target=worker).start()
threading.thread(target=set_event).start()
适用于:
- 线程间同步
- 控制多个线程的启动时机
总结
| 锁类型 | 适用范围 | 主要作用 |
|---|---|---|
threading.lock() | 线程间同步 | 互斥访问共享资源 |
multiprocessing.lock() | 进程间同步 | 互斥访问进程共享资源 |
threading.rlock() | 递归调用 | 允许同一线程多次获取锁 |
threading.semaphore(n) | 线程池/连接池 | 限制并发线程数 |
threading.condition() | 线程间通信 | 等待/通知机制(生产者-消费者) |
threading.event() | 线程间信号 | 事件触发机制 |
在多线程/多进程编程中,正确使用 锁 机制可以防止数据竞争、保持数据一致性,提高程序的可靠性和可维护性。
到此这篇关于python中锁lock的类型举例详解的文章就介绍到这了,更多相关python锁lock类型详解内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论