- 信号量在生产者 - 消费者模型中实现并发控制与同步的原理:
- 同步:信号量用于协调生产者和消费者的操作顺序。生产者在生产数据后,通过信号量通知消费者有新数据可用;消费者在消费数据前,通过信号量等待有数据可用。
- 并发控制:信号量可以限制同时访问共享资源(如缓冲区)的线程数量。例如,通过设置信号量的初值来控制缓冲区的可用槽位数量,防止生产者在缓冲区满时继续写入,以及消费者在缓冲区空时继续读取。
- 伪代码示例:
// 定义信号量
Semaphore empty; // 表示缓冲区中的空闲槽位
Semaphore full; // 表示缓冲区中的已占用槽位
Semaphore mutex; // 用于保护共享缓冲区的互斥访问
// 初始化信号量
empty = 缓冲区大小;
full = 0;
mutex = 1;
// 生产者线程
Producer() {
while (true) {
// 生产数据
data = produceData();
empty.wait(); // 等待缓冲区有空闲槽位
mutex.wait(); // 进入临界区,保护共享缓冲区
// 将数据放入缓冲区
putDataToBuffer(data);
mutex.signal(); // 离开临界区
full.signal(); // 通知缓冲区有新数据
}
}
// 消费者线程
Consumer() {
while (true) {
full.wait(); // 等待缓冲区有数据
mutex.wait(); // 进入临界区,保护共享缓冲区
// 从缓冲区取出数据
data = getDataFromBuffer();
mutex.signal(); // 离开临界区
empty.signal(); // 通知缓冲区有空闲槽位
// 消费数据
consumeData(data);
}
}
- 信号量初值设置及原因:
empty
信号量:初值设为缓冲区大小。原因是它代表缓冲区中初始的空闲槽位数量,生产者在向缓冲区写入数据前需要获取empty
信号量,只有当缓冲区有空闲槽位时才能写入数据,从而防止缓冲区溢出。
full
信号量:初值设为0。因为初始时缓冲区中没有数据,消费者在从缓冲区读取数据前需要获取full
信号量,只有当缓冲区有数据(即full
信号量值大于0)时才能读取,从而防止消费者从空缓冲区读取数据。
mutex
信号量:初值设为1。它用于保护共享缓冲区,确保同一时间只有一个线程(生产者或消费者)可以访问缓冲区,实现互斥访问,避免数据竞争。