面试题答案
一键面试1. 信号量预防死锁原理
在多线程编程中,死锁通常发生在多个线程互相等待对方释放资源的情况下。信号量可以用来控制同时访问资源的线程数量。通过合理分配信号量,使得线程在获取资源前先获取信号量,使用完资源后释放信号量,避免多个线程同时获取所有资源,从而预防死锁。
2. 代码实现
import threading
import time
# 假设这是有限数量的资源
resource_count = 3
# 创建信号量,初始值为资源数量
semaphore = threading.Semaphore(resource_count)
def worker(worker_id):
print(f"Worker {worker_id} 尝试获取资源")
# 获取信号量,如果信号量为0,线程会阻塞直到有信号量可用
semaphore.acquire()
try:
print(f"Worker {worker_id} 获取到资源,开始工作")
# 模拟工作
time.sleep(2)
print(f"Worker {worker_id} 工作完成,释放资源")
finally:
# 释放信号量,让其他线程有机会获取
semaphore.release()
# 创建多个线程
threads = []
for i in range(5):
t = threading.Thread(target=worker, args=(i,))
threads.append(t)
t.start()
# 等待所有线程完成
for t in threads:
t.join()
3. 代码解释
- 信号量创建:
semaphore = threading.Semaphore(resource_count)
创建了一个信号量对象,初始值为resource_count
,即资源的数量。 - 获取信号量:在
worker
函数中,semaphore.acquire()
用于获取信号量。如果当前信号量的值大于0,信号量的值减1,线程继续执行;如果信号量的值为0,线程会被阻塞,直到有其他线程释放信号量。 - 释放信号量:在
try - finally
块中,semaphore.release()
用于释放信号量,将信号量的值加1,让其他线程有机会获取信号量。 - 多线程创建与启动:通过循环创建多个线程,并启动它们。每个线程都会尝试获取信号量来访问资源,从而展示了多个线程对资源的竞争访问以及信号量的控制逻辑。