面试题答案
一键面试常用线程同步机制
- 锁(Lock):也叫互斥锁,一次只允许一个线程进入临界区,访问共享资源,用于保证同一时间只有一个线程可以执行特定代码块。
- 信号量(Semaphore):控制同时访问共享资源的线程数量,允许指定数量的线程同时进入临界区。
- 事件(Event):用于线程间通信,一个线程可以通过设置或清除事件来通知其他线程执行或等待。
- 条件变量(Condition):通常与锁一起使用,允许线程在满足特定条件时才执行,用于复杂的线程同步场景。
示例:使用锁(Lock)避免线程安全问题
import threading
# 共享资源
counter = 0
lock = threading.Lock()
def increment():
global counter
for _ in range(1000000):
# 获取锁
lock.acquire()
try:
counter += 1
finally:
# 释放锁
lock.release()
# 创建两个线程
thread1 = threading.Thread(target=increment)
thread2 = threading.Thread(target=increment)
# 启动线程
thread1.start()
thread2.start()
# 等待线程执行完毕
thread1.join()
thread2.join()
print(f"Final counter value: {counter}")
在上述代码中,lock.acquire()
用于获取锁,确保同一时间只有一个线程能执行 counter += 1
这一操作,lock.release()
用于释放锁,使得其他线程有机会获取锁并执行临界区代码。
不同同步机制适用场景
- 锁(Lock):适用于简单场景,当同一时间只允许一个线程访问共享资源时使用,例如对共享变量的读写操作。
- 信号量(Semaphore):适用于需要限制同时访问共享资源的线程数量的场景,如数据库连接池,限制同时连接数据库的线程数。
- 事件(Event):适用于一个线程需要根据另一个线程的状态来决定是否继续执行的场景,例如主线程等待子线程完成初始化后再继续执行后续操作。
- 条件变量(Condition):适用于线程需要在特定条件满足时才执行的复杂场景,例如生产者 - 消费者模型中,消费者线程等待生产者线程生产出足够的产品后才开始消费。