面试题答案
一键面试锁的作用
在Python多线程编程中,锁的主要作用是避免多个线程同时访问共享资源,从而防止数据竞争问题。当一个线程获取到锁时,其他线程必须等待锁被释放后才能获取锁并访问共享资源,这样可以确保在同一时刻只有一个线程能够修改共享资源,保证数据的一致性和完整性。
Lock
和RLock
的区别
Lock
(普通锁):- 是一种简单的互斥锁。
- 当一个线程获取锁后,其他线程必须等待该锁被释放才能获取。
- 如果一个线程尝试获取已经被自己锁定的
Lock
,会导致死锁,因为它无法再次获取已经持有的锁。
RLock
(可重入锁):- 允许同一个线程多次获取锁,而不会导致死锁。
- 每次获取锁时,锁的内部计数器加1,每次释放锁时,计数器减1。只有当计数器为0时,锁才会真正被释放,其他线程才能获取。
多线程访问共享字典场景下使用锁避免数据竞争示例
import threading
# 创建共享字典和锁
shared_dict = {}
lock = threading.Lock()
# rlock = threading.RLock() # 如果使用可重入锁,替换为这行
def update_dict(key, value):
# 获取锁
lock.acquire()
try:
shared_dict[key] = value
finally:
# 释放锁
lock.release()
# 创建多个线程并启动
threads = []
for i in range(5):
t = threading.Thread(target=update_dict, args=(i, i * 2))
threads.append(t)
t.start()
# 等待所有线程执行完毕
for t in threads:
t.join()
print(shared_dict)
在上述示例中,定义了一个共享字典shared_dict
和一个锁lock
。在update_dict
函数中,通过lock.acquire()
获取锁,确保在修改共享字典时其他线程不能同时进行修改,修改完成后通过lock.release()
释放锁。如果使用RLock
,获取和释放锁的操作与Lock
相同,只是同一个线程可以多次获取RLock
而不会死锁。