进程模拟生产者-消费者问题

这里我只是简单实现了这个经典问题的思路与想打,并且书写的程序也是能正确的运行出合理的答案,希望今后还可以改进程序使之更加完善

思路描述:

1.生产者进程:产生一个数据,当要送入缓冲区的时候,要检查缓冲区是否已满,若未满,则可将数据送入缓冲区,并通知消费者进程,否则等待

2.对于消费者进程:当它去取数据的时候,要看缓冲区中是否有数据可以去取,若有则取走一个数据,并通知生产者进程,否则等待

3.缓冲区是一个临界资源,因此,诸进程对缓冲区的操作程序是一个共享临界区,所以这里还有一个互斥问题

public class question_test {

	public static void main(String[] args) {
		
		//主方法
		Mutex mtex = new Mutex();
		mtex.setFull(0); //设置缓存区最大存放10个产品
		mtex.setMutex(false); //缓存区默认状态为未使用
		
		//创建消费者进程
		Customer c1 = new Customer(mtex);
		Customer c2 = new Customer(mtex);
		Customer c3 = new Customer(mtex);
		Customer c4 = new Customer(mtex);
		Customer c5 = new Customer(mtex);
		Customer c6 = new Customer(mtex);
		Customer c7 = new Customer(mtex);
		
		//创建生产者进程
		Producer p1 = new Producer(mtex);
		Producer p2 = new Producer(mtex);
		Producer p3 = new Producer(mtex);
		Producer p4 = new Producer(mtex);
		Producer p5 = new Producer(mtex);
		Producer p6 = new Producer(mtex);
		Producer p7 = new Producer(mtex);
		
		//启动消费者,生产者进程
		p1.start();
		p2.start();
		p3.start();
		p4.start();
		p5.start();
		p6.start();
		p7.start();
		c1.start();
		c2.start();
		c3.start();
		c4.start();
		c5.start();
		c6.start();
		c7.start();
	}

}

class Mutex {
	//判断互斥变量,是否可以使用临界资源(缓冲区)
	private boolean mutex;
	private int full;

	public int getFull() {
		return full;
	}

	public void setFull(int full) {
		this.full = full;
	}

	public boolean isMutex() {
		return mutex;
	}

	public void setMutex(boolean mutex) {
		this.mutex = mutex;
	}
}

class Customer extends Thread{
	Customer(Mutex mtx){
		this.mtx = mtx;
	}
	public Mutex mtx;
	
	//申请缓冲区
	public void p_cus(){
			//判断缓冲区中是否有资源可以去取
			if(mtx.getFull()>0){
				//判断缓冲区是否被使用
				if(mtx.isMutex()){
					//这里没有写等待,若是加入等待可用sleep()方法
					//我在这里直接是打印出相关消息
					System.out.println("生产者正在向缓冲区中放产品,消费者无法使用缓冲区!!!");
				}else{
					mtx.setMutex(true);
					mtx.setFull(mtx.getFull()-1);
					System.out.println("消费者消费1件产品,当前库存:"+mtx.getFull());
				}
			}else{
				System.out.println("缓存区无产品!!!");
			}
		}	
	
	//释放缓冲区使用权
	public void v_cusmex(){
		mtx.setMutex(false);
	}
	
	//重写run方法,调用申请与释放缓冲区函数
	public void run(){
			p_cus();
			v_cusmex();
	}
	
}

class Producer extends Thread{
	Producer(Mutex mtx){
		this.mtx = mtx;
	}
	//访问缓存区互斥判断当为true表示正在访问缓存区。
	public Mutex mtx;
	
	//生产一个产品;
	public void p_pro(){
			//这里默认缓冲区最多存放30个资源,同消费者一样进行相应的判断
			if(mtx.getFull()<30&&mtx.getFull()>=0){
				if(mtx.isMutex()){
					//只是简单地输出相关状态信息,如果想让进城等待加入sleep函数
					System.out.println("消费者正在从缓冲区中取产品,生产者无法使用缓冲区!!!");
				}else{
					mtx.setMutex(true);
					mtx.setFull(mtx.getFull()+1);
					System.out.println("产品已经生产放入缓冲区,当前库存:"+mtx.getFull());
				}
			}else{
				System.out.println("仓库已满!暂时不能生产!");
			}
	}
	
	public void v_promex(){
		mtx.setMutex(false);
	}
	
	//重写run方法,调用申请与释放缓冲区函数
	public void run(){
			p_pro();
			v_promex();
	}	
}






这就是模拟出来的效果,希望可以帮助到你理解这个经典的进程调度问题!



  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这个是很经典的问题 实验题目: 生产者消费者(综合性实验) 实验环境: C语言编译器 实验内容: ① 由用户指定要产生的进程及其类别,存入进入就绪队列。    ② 调度程序从就绪队列中提取一个就绪进程运行。如果申请的资源被阻塞则进入相应的等待队列,调度程序调度就绪队列中的下一个进程进程运行结束时,会检查对应的等待队列,激活队列中的进程进入就绪队列。运行结束的进程进入over链表。重复这一过程直至就绪队列为空。    ③ 程序询问是否要继续?如果要转直①开始执行,否则退出程序。 实验目的: 通过实验模拟生产者消费者之间的关系,了解并掌握他们之间的关系及其原理。由此增加对进程同步的问题的了解。 实验要求: 每个进程有一个进程控制块(PCB)表示。进程控制块可以包含如下信息:进程类型标号、进程系统号、进程状态、进程产品(字符)、进程链指针等等。 系统开辟了一个缓冲区,大小由buffersize指定。 程序中有三个链队列,一个链表。一个就绪队列(ready),两个等待队列:生产者等待队列(producer);消费者队列(consumer)。一个链表(over),用于收集已经运行结束的进程 本程序通过函数模拟信号量的操作。 参考书目: 1)徐甲同等编,计算机操作系统教程,西安电子科技大学出版社 2)Andrew S. Tanenbaum著,陈向群,马红兵译. 现代操作系统(第2版). 机械工业出版社 3)Abranham Silberschatz, Peter Baer Galvin, Greg Gagne著. 郑扣根译. 操作系统概念(第2版). 高等教育出版社 4)张尧学编著. 计算机操作系统教程(第2版)习题解答与实验指导. 清华大学出版社 实验报告要求: (1) 每位同学交一份电子版本的实验报告,上传到202.204.125.21服务器中。 (2) 文件名格式为班级、学号加上个人姓名,例如: 电子04-1-040824101**.doc   表示电子04-1班学号为040824101号的**同学的实验报告。 (3) 实验报告内容的开始处要列出实验的目的,实验环境、实验内容等的说明,报告中要附上程序代码,并对实验过程进行说明。 基本数据结构: PCB* readyhead=NULL, * readytail=NULL; // 就绪队列 PCB* consumerhead=NULL, * consumertail=NULL; // 消费者队列 PCB* producerhead=NULL, * producertail=NULL; // 生产者队列 over=(PCB*)malloc(sizeof(PCB)); // over链表 int productnum=0; //产品数量 int full=0, empty=buffersize; // semaphore char buffer[buffersize]; // 缓冲区 int bufferpoint=0; // 缓冲区指针 struct pcb { /* 定义进程控制块PCB */ int flag; // flag=1 denote producer; flag=2 denote consumer; int numlabel; char product; char state; struct pcb * processlink; …… }; processproc( )--- 给PCB分配内存。产生相应的的进程:输入1为生产者进程;输入2为消费者进程,并把这些进程放入就绪队列中。 waitempty( )--- 如果缓冲区满,该进程进入生产者等待队列;linkqueue(exe,&producertail); // 把就绪队列里的进程放入生产者队列的尾部 void signalempty() bool waitfull() void signalfull() void producerrun() void comsuerrun() void main() { processproc(); element=hasElement(readyhead); while(element){ exe=getq(readyhead,&readytail); printf("进程%d申请运行,它是一个",exe->numlabel); exe->flag==1? printf("生产者\n"):printf("消费者\n"); if(exe->flag==1) producerrun(); else comsuerrun(); element=hasElement(readyhead); } printf("就绪队列没有进程\n"); if(hasElement(consumerhead)) { printf("消费者等待队列中有进程:\n"); display(consumerhead); } else { printf("消费者等待队列中没有进程\n"); } if(hasElement(producerhead)) { printf("生产者等待队列中有进程:\n"); display(producerhead); } else { printf("生产者等待队列中没有进程\n"); } }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值