- 使用锁机制(如
threading.Lock
):
- 原理:在执行关键操作(可能导致线程不安全的部分)前获取锁,操作完成后释放锁。其他线程在锁被占用时无法进入该关键操作区域,从而保证同一时间只有一个线程执行该关键操作,实现线程安全。例如:
import threading
lock = threading.Lock()
data = 0
def increment():
global data
lock.acquire()
try:
data = data + 1
finally:
lock.release()
- 使用队列(
queue.Queue
):
- 原理:队列本身是线程安全的。线程将任务放入队列,另一个或多个线程从队列中取出任务执行。由于队列的内部实现保证了对其操作的原子性,所以可以避免竞争条件,实现线程安全。例如:
import threading
import queue
q = queue.Queue()
def worker():
while True:
item = q.get()
if item is None:
break
# 处理任务
q.task_done()
# 创建线程
thread = threading.Thread(target = worker)
thread.start()
# 放入任务
q.put(1)
q.put(2)
q.join()
q.put(None)
thread.join()
- 使用
threading.local()
:
- 原理:
threading.local()
为每个线程创建独立的存储空间。不同线程对threading.local()
实例的属性操作,不会相互干扰,因为它们操作的是各自独立的副本,从而保证线程安全。例如:
import threading
local_data = threading.local()
def set_local_value(value):
local_data.value = value
def get_local_value():
return local_data.value
thread1 = threading.Thread(target = set_local_value, args=(1,))
thread2 = threading.Thread(target = set_local_value, args=(2,))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print(get_local_value()) # 在主线程中这里获取不到值,因为主线程没有设置