在 Python 中,线程锁(Thread Lock)是一种同步原语,用于在多线程环境中协调线程之间的访问,避免多个线程同时访问共享资源时出现竞态条件(Race Condition)。线程锁确保在任何时刻只有一个线程可以访问特定的资源。为了实现线程锁,Python的threading模块提供了Lock类,下面将先简单介绍下Lock类的一些基础概念和用法。
1. threading.Lock()
Lock 是一个简单的同步原语,它用于确保同一时刻只有一个线程能够访问共享资源。当一个线程获得了锁,其他线程必须等待直到该锁被释放。
1.1 Lock基本用法
基本用法如下:
import threading
# 创建一个锁对象
lock = threading.Lock()
# 用锁保护共享资源
lock.acquire() # 获取锁
# 临界区: 共享资源的访问代码
lock.release() # 释放锁
Lock 是一种 互斥锁,即同一时刻只能有一个线程获取锁并执行临界区代码。其中acquire() 方法用来请求锁,release() 方法用来释放锁。具体来说,acquire()尝试获取锁,如果锁此时被其他进程占用,则当前线程阻塞,直到锁可以用为止。而release()则是将当前占用的锁进行释放,让其他线程进入临界区。
下面是一段示例代码:
import threading
# 共享资源
shared_data = 0
# 创建一个锁对象
lock = threading.Lock()
# 线程函数
def increment():
global shared_data
for _ in range(1000000):
# 获取锁
with lock:
shared_data += 1 # 访问共享资源
# 创建多个线程
threads = [threading.Thread(target=increment) for _ in range(2)]
# 启动线程
for thread in threads:
thread.start()
# 等待线程完成
for thread in threads:
thread.join()
print(f"Final shared data: {shared_data}")
# 当没有加锁时,输出结果为:
Final shared data: 1990922
# 加锁后,输出结果为:
Final shared data: 2000000
1.2 Lock的属性和方法
-
acquire(blocking=True, timeout=-1):
- 获取锁。如果 blocking 为 True(默认值),那么如果锁已被占用,调用线程会阻塞直到锁可用。如果 blocking 为 False,则不会阻塞,直接返回 False。如果传入 timeout,则在指定时间内尝试获取锁,若超时则返回 False。
-
release():
- 释放锁。如果锁没有被当前线程持有,调用该方法会抛出 RuntimeError。
-
locked():
- 返回一个布尔值