面试题答案
一键面试Event对象工作原理
Event
对象是线程间通信的简单机制,它包含一个内部标志。线程可以通过set()
方法将这个标志设为True
,通过clear()
方法将其设为False
。其他线程可以调用wait()
方法来阻塞,直到标志变为True
。当Event
对象的标志为True
时,调用wait()
方法的线程将立即继续执行,而不会阻塞。
Condition对象工作原理
Condition
对象用于更复杂的线程同步场景。它结合了锁(Lock
)和条件变量的功能。线程可以通过acquire()
方法获取锁,通过release()
方法释放锁。Condition
对象提供了wait()
、notify()
和notify_all()
方法。当一个线程调用wait()
时,它会释放锁并进入等待状态,直到其他线程调用notify()
或notify_all()
唤醒它。唤醒后,线程会重新获取锁才继续执行。
优先选择Event的情况
当需要简单的线程间信号通知,即一个线程需要告知其他线程某个事件已经发生,不需要复杂的同步逻辑时,优先选择Event
。例如,一个线程负责监控文件是否被创建,当文件创建后通知其他线程进行处理。
Event应用场景代码示例
import threading
import time
def monitor_file(event):
print('开始监控文件')
time.sleep(5)
print('文件已创建')
event.set()
def process_file(event):
print('等待文件创建')
event.wait()
print('开始处理文件')
if __name__ == '__main__':
event = threading.Event()
t1 = threading.Thread(target=monitor_file, args=(event,))
t2 = threading.Thread(target=process_file, args=(event,))
t1.start()
t2.start()
t1.join()
t2.join()
优先选择Condition的情况
当线程间需要更复杂的同步,比如多个线程依赖不同条件进行协作,或者需要在等待条件时执行一些清理操作时,使用Condition
更合适。例如,生产者 - 消费者模型中,消费者需要等待生产者生产出产品后才能消费,并且可能存在多个消费者和生产者。
Condition应用场景代码示例
import threading
import time
class Queue:
def __init__(self):
self.items = []
self.max_size = 5
self.cond = threading.Condition()
def put(self, item):
with self.cond:
while len(self.items) >= self.max_size:
print('队列已满,生产者等待')
self.cond.wait()
self.items.append(item)
print(f'生产者生产: {item}')
self.cond.notify()
def get(self):
with self.cond:
while not self.items:
print('队列为空,消费者等待')
self.cond.wait()
item = self.items.pop(0)
print(f'消费者消费: {item}')
self.cond.notify()
return item
def producer(queue):
for i in range(10):
queue.put(i)
time.sleep(1)
def consumer(queue):
for _ in range(10):
queue.get()
time.sleep(1)
if __name__ == '__main__':
q = Queue()
t1 = threading.Thread(target=producer, args=(q,))
t2 = threading.Thread(target=consumer, args=(q,))
t1.start()
t2.start()
t1.join()
t2.join()