前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Linux】利用 <信号量> 实现 <生产者-消费者模型-线程同步 >(思维导图&代码演示&思路解析)

【Linux】利用 <信号量> 实现 <生产者-消费者模型-线程同步 >(思维导图&代码演示&思路解析)

作者头像
YY的秘密代码小屋
发布2024-11-03 08:05:12
2380
发布2024-11-03 08:05:12
举报
文章被收录于专栏:C++系列

一.什么是生产者消费者模型

生产者消费者问题(Producer-Consumer Problem)通常用于多线程编程中的线程间通信和同步。

  1. 该问题描述了两个线程(或进程)之间的协作: 一个或多个生产者线程生成数据项,并将它们放入 缓冲区 ;一个或多个消费者线程从 缓冲区 取出数据项,并进行处理。
  2. 这个过程中,生产者和消费者需要同步,以避免竞争条件和资源冲突。

二.生产者和消费者各只有一人,缓冲区单元只有一个,用P、V原语实现生产者和消费者的同步操作

题目:

  • 对于生产者-消费者问题,若缓冲区中缓冲区单元只有一个,生产者和消费者各只有一人。用P、V原语实现生产者和消费者的同步操作

解析:

  1. 设置两个信号量,empty full
  2. 生产者会等待empty,等待缓冲区为空
  3. 消费者会等待full,等待缓冲区满
  4. 一开始缓冲区是空的,所以设置时,empty=1,先进去;Semaphore empty = 1; Semaphore full = 0;
  5. 生产者线程和消费者线程, 彼此互相唤醒对方的信号量 ,即可

流程图演示:

1
1
代码语言:javascript
复制
// 信号量初始化  
Semaphore empty = 1;  // 缓冲区空闲单元数量  
Semaphore full = 0;   // 缓冲区已占用单元数量  

Buffer buffer;  // 缓冲区

// 生产者线程  
void producer() {  
	    while (true) {  
	        // 生产一个数据项  
	        item = produceItem();   
	        
            // 等待缓冲区有空闲单元  
	        P(empty);  

	        // 将数据项放入缓冲区  
	        buffer = item;  
 
	        // 通知消费者缓冲区中有数据  
	        V(full);  
	        }  
}  
// 消费者线程  
void consumer() {  
	    while (true) {  
	        // 等待缓冲区有数据  
	        P(full);  
 
	        // 从缓冲区中取出数据项  
	        item = buffer;  

           // 通知生产者缓冲区中有一个空闲单元  
	        V(empty);  
	  
           // 消费数据项  
	        consumeItem(item);  
	    }  
}

三.生产者和消费者各只有一人,缓冲区单元有n个,用P、V原语实现生产者和消费者的同步操作

题目:

  • 对于生产者-消费者问题,若缓冲区中缓冲区的单元有n个,生产者和消费者各只有一个。用P、V原语实现生产者和消费者同步操作。

主干部分解析:

  1. 设置两个信号量,empty full
  2. 生产者会等待empty,等待缓冲区为空
  3. 消费者会等待full,等待缓冲区满
  4. 一开始缓冲区是空的,所以设置时,empty=1,先进去;Semaphore empty = 1; Semaphore full = 0;
  5. 生产者线程和消费者线程, 彼此互相唤醒对方的信号量 ,即可

改动部分解析:

  1. 缓冲区单元有n个,所以用 数组 的形式表示缓冲区,Buffer[n] buffer;
  2. 设置两个索引in out
  3. in 给生产者使用,表示指向下一个空闲缓冲区的索引
  4. out 给消费者使用,表示指向下一个有数据缓冲区的索引
  5. 其中,小算法(in/out+1)%n 实现了循环

流程图演示:

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
// 信号量初始化  
Semaphore empty = n;  // 缓冲区空闲单元数量,初始为n 
Semaphore full = 0;   // 缓冲区已占用单元数量  

Buffer[n] buffer;     // 大小为n的缓冲区数组  
int in = 0;           // 指向下一个空闲缓冲区的索引(生产者使用)  
int out = 0;          // 指向下一个有数据缓冲区的索引(消费者使用)  

// 生产者线程  
void producer() {  
	    while (true) {  
	        // 生产一个数据项  
	        item = produceItem();   
	        
            // 等待缓冲区有空闲单元  
	        P(empty);  

            // 将数据项放入缓冲区
 	        buffer[in] = item;  
	        in = (in + 1) % n;  // 循环使用缓冲区  
	        
	        // 通知消费者缓冲区中有数据  
	        V(full);  
	        }  
}  
// 消费者线程  
void consumer() {  
	    while (true) {  
	        // 等待缓冲区有数据  
	        P(full);  
 
	        // 从缓冲区中取出数据项  
	        item = buffer[out];  
	        out = (out + 1) % n;  // 循环使用缓冲区
	        
           // 通知生产者缓冲区中有一个空闲单元  
	        V(empty);  
	  
           // 消费数据项  
	        consumeItem(item);  
	    }  
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-11-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一.什么是生产者消费者模型
  • 二.生产者和消费者各只有一人,缓冲区单元只有一个,用P、V原语实现生产者和消费者的同步操作
  • 三.生产者和消费者各只有一人,缓冲区单元有n个,用P、V原语实现生产者和消费者的同步操作
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档