操作系统实验报告--经典的生产者—消费者问题

  • 格式:doc
  • 大小:418.00 KB
  • 文档页数:8

下载文档原格式

  / 8
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验二经典的生产者—消费者问题

一、目的

实现对经典的生产者—消费者问题的模拟,以便更好的理解经典进程同步问题。

二、实验内容及要求

编制生产者—消费者算法,模拟一个生产者、一个消费者,共享一个缓冲池的情形。

1、实现对经典的生产者—消费者问题的模拟,以便更好的理解此经典进程同步问题。生产者-消费者问题是典型的PV操作问题,假设系统中有一个比较大的缓冲池,生产者的任务是只要缓冲池未满就可以将生产出的产品放入其中,而消费者的任务是只要缓冲池未空就可以从缓冲池中拿走产品。缓冲池被占用时,任何进程都不能访问。

2、每一个生产者都要把自己生产的产品放入缓冲池,每个消费者从缓冲池中取走产品消费。在这种情况下,生产者消费者进程同步,因为只有通过互通消息才知道是否能存入产品或者取走产品。他们之间也存在互斥,即生产者消费者必须互斥访问缓冲池,即不能有两个以上的进程同时进行。

三、生产者和消费者原理分析

在同一个进程地址空间内执行两个线程。生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。消费者线程从缓冲区中获得物品,然后释放缓冲区。当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放一个空缓冲区。当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻挡,直到新的物品被生产出来。

四、生产者与消费者功能描述:

生产者功能描述:在同一个进程地址空间内执行两个线程。生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区。

消费者功能描述:消费者线程从缓冲区获得物品,然后释放缓冲区,当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来。

五、实验环境

操作系统环境:Windows系统。

编程语言:C#。

六、生产者与消费者的思路和设计

1、程序流程图

(1) 生产者

(2) 消费者

2、主要程序代码

//初始化变量

private void Form1_Load(object sender, EventArgs e)

{

mutex = 1; //互斥信号量

full = 0; //缓冲池中满缓冲区的数量

empty = 5;//缓冲池中空缓冲区的数量

count1 = 0;//生产的产品数目

i = 0;

lb_mutex.Text = "1";

lb_full.Text = "0";

lb_empty.Text = "5";

}

//消费者从缓冲区中消费一个产品

private void consumer_Click(object sender, EventArgs e)

{

if (full > 0)

{ //消费者已进入互斥临界区

if (mutex == 1) //申请进入临界区

{

mutex = 0; //消费者已进入互斥临界区

lb_mutex.Text = "0";

timer_consumer.Enabled = true;//启动消费者消费缓冲区产品

}

else

{

MessageBox.Show("缓冲区被占用,请等待。。。", "信息提"MessageBoxButtons.OK);

}

}

else

{

MessageBox.Show("缓冲区为空,不能消费!", "信息提示", MessageBoxButtons.OK);

}

}

//生产者向缓冲区中存入一个产品

private void producer_Click(object sender, EventArgs e)

{

count1 = count1 + 1; //生产一个产品

if (empty > 0)

{ //有缓冲区可放产品

if (mutex == 1)

{ //申请进入临界区

mutex = 0; //生产者已进入临界区

lb_mutex.Text = "0";

timer1.Start(); //启动生产者将产品放入缓冲区

}

else

{ //不能进入临界区

count1 = count1 - 1;

MessageBox.Show("缓冲区被占用,请等待。。。", "信息提示", MessageBoxButtons.OK);

}

}

else

{

MessageBox.Show("缓冲区已满!", "信息提示", MessageBoxButtons.OK); //无缓冲区可放产品count1 = count1 - 1;

}

}

//生产者

private void timer1_Tick_1(object sender, EventArgs e)

{

if (bool1)

{

switch (count1)

{

case 1: pictureBox1.Visible = true; break;

case 2: pictureBox2.Visible = true; break;

case 3: pictureBox3.Visible = true; break;

case 4: pictureBox4.Visible = true; break;

case 5: pictureBox5.Visible = true; break;

}

lb_show.Text = "生产者进程占用缓冲区,请等待。。。。";

bool1 = false;

}

else

{

switch (count1)

{

case 1: pictureBox1.Visible = false; break;

case 2: pictureBox2.Visible = false; break;

case 3: pictureBox3.Visible = false; break;

case 4: pictureBox4.Visible = false; break;

case 5: pictureBox5.Visible = false; break;

}

lb_show.Text = "生产者进程占用缓冲区,请等待。。。。";

bool1 = true;

}

i = i + 1;

if (i == 5)

{ //循环缓冲区,首尾相接