MST

星途 面试题库

面试题:并发与同步之条件变量基础

请简要描述条件变量在操作系统线程通信机制中的作用,并且说明它与互斥锁的配合使用方式。
31.3万 热度难度
操作系统并发与同步

知识考点

AI 面试

面试题答案

一键面试

条件变量在操作系统线程通信机制中的作用

  1. 线程同步:条件变量用于协调线程间的同步,使线程能够在特定条件满足时被唤醒并继续执行。在多线程编程中,常常会出现一个线程需要等待某个条件满足后才能继续执行的情况,例如生产者 - 消费者模型中,消费者线程需要等待缓冲区有数据才能消费。条件变量就提供了一种机制,让线程可以阻塞等待某个条件,而不是通过不断轮询浪费 CPU 资源。
  2. 避免忙等待:如果没有条件变量,线程可能会通过不断检查条件来确定是否可以继续执行,这被称为忙等待。忙等待会消耗大量的 CPU 时间,而条件变量允许线程在条件不满足时进入睡眠状态,当条件满足时由其他线程唤醒,从而避免了这种无意义的 CPU 消耗。

条件变量与互斥锁的配合使用方式

  1. 初始化:首先需要分别初始化互斥锁和条件变量。在大多数操作系统的线程库中(如 POSIX 线程库),可以使用相应的函数进行初始化,例如 pthread_mutex_init 初始化互斥锁,pthread_cond_init 初始化条件变量。
  2. 保护共享资源:互斥锁用于保护共享资源,确保同一时间只有一个线程能够访问共享资源。当一个线程想要操作共享资源时,它必须先获取互斥锁。例如,在生产者 - 消费者模型中,缓冲区就是共享资源,无论是生产者向缓冲区写入数据还是消费者从缓冲区读取数据,都需要先获取互斥锁。
  3. 等待条件:当一个线程需要等待某个条件时(例如消费者线程等待缓冲区有数据),它会先获取互斥锁,然后检查条件是否满足。如果条件不满足,线程会调用条件变量的等待函数(如 pthread_cond_wait)。这个函数会做两件事:一是自动释放它已经获取的互斥锁(这样其他线程就可以访问共享资源来改变条件),二是将当前线程置于等待状态。
  4. 唤醒线程:当另一个线程改变了条件(例如生产者向缓冲区写入了数据),它会获取互斥锁(因为可能需要操作共享资源来通知其他线程),然后调用条件变量的唤醒函数(如 pthread_cond_signal 唤醒一个等待的线程,或 pthread_cond_broadcast 唤醒所有等待的线程)。唤醒函数不会自动释放互斥锁,唤醒操作完成后,调用者需要手动释放互斥锁。
  5. 重新获取互斥锁并检查条件:被唤醒的线程从等待状态返回后,会自动重新获取互斥锁(因为之前等待时已经释放了)。然后线程再次检查条件,因为在它被唤醒到重新获取互斥锁的这段时间内,条件可能又发生了变化。如果条件仍然不满足,线程可能会再次调用条件变量的等待函数继续等待。

通过这种方式,条件变量和互斥锁紧密配合,实现了线程间高效且安全的同步与通信。