MST

星途 面试题库

面试题:并发与同步:操作系统条件变量在生产者 - 消费者模型中的应用

请描述在生产者 - 消费者模型中,如何使用操作系统的条件变量来实现线程间的同步。请给出关键代码片段(可使用伪代码或你熟悉的编程语言),并解释条件变量的等待和唤醒机制在该模型中的作用。
47.2万 热度难度
操作系统并发与同步

知识考点

AI 面试

面试题答案

一键面试

关键代码片段(以Python为例)

import threading

# 创建锁和条件变量
lock = threading.Lock()
condition = threading.Condition(lock)

# 共享资源,例如一个队列
queue = []
MAX_SIZE = 5

# 生产者线程函数
def producer(id):
    global queue
    while True:
        with lock:
            while len(queue) >= MAX_SIZE:
                # 队列已满,生产者等待
                condition.wait()
            item = id * 10 + len(queue)
            queue.append(item)
            print(f"Producer {id} produced {item}")
            # 唤醒消费者
            condition.notify()

# 消费者线程函数
def consumer(id):
    global queue
    while True:
        with lock:
            while len(queue) == 0:
                # 队列已空,消费者等待
                condition.wait()
            item = queue.pop(0)
            print(f"Consumer {id} consumed {item}")
            # 唤醒生产者
            condition.notify()

# 创建生产者和消费者线程
producer_thread1 = threading.Thread(target=producer, args=(1,))
consumer_thread1 = threading.Thread(target=consumer, args=(1,))

# 启动线程
producer_thread1.start()
consumer_thread1.start()

# 等待线程结束(这里实际上不会结束,因为是无限循环)
producer_thread1.join()
consumer_thread1.join()

条件变量的等待和唤醒机制在该模型中的作用

  1. 等待机制
    • 生产者:当共享队列已满(len(queue) >= MAX_SIZE)时,生产者调用condition.wait()。此时,生产者线程会释放它持有的锁(这里是lock),并进入等待状态。这样其他线程(如消费者线程)就有机会获取锁并操作共享队列。
    • 消费者:当共享队列已空(len(queue) == 0)时,消费者调用condition.wait()。消费者线程同样会释放锁并进入等待状态,以便其他线程(如生产者线程)能够获取锁并向队列中添加数据。
  2. 唤醒机制
    • 生产者:当生产者向队列中添加了数据后,调用condition.notify()。这会唤醒一个等待在条件变量上的线程(可能是消费者线程)。被唤醒的线程会尝试重新获取锁,一旦获取到锁,就可以继续执行(例如消费者开始消费数据)。
    • 消费者:当消费者从队列中取出数据后,也调用condition.notify()。这会唤醒一个等待在条件变量上的线程(可能是生产者线程),使得生产者可以继续向队列中添加数据。

通过条件变量的等待和唤醒机制,生产者 - 消费者模型可以有效地实现线程间的同步,避免了资源竞争和死锁等问题,保证了共享资源(队列)的正确使用。