生产者与消费者问题的模拟实现

合集下载

生产者与消费者问题的模拟实现

生产者与消费者问题的模拟实现

操作系统课程设计报告专业计算机科学与技术学生姓名郑伟班级BM计算机091 学号0951401123指导教师李先锋完成日期2011年12月31日博雅学院题目:生产者与消费者问题的模拟实现一、设计目的本课程设计是学习完“操作系统原理”课程后进行的一次全面的综合训练,通过课程设计,更好地掌握操作系统的原理及实现方法,加深对操作系统基础理论和重要算法的理解,加强学生的动手能力。

二、设计内容1)概述用多进程同步方法解决生产者-消费者问题,C或C++语言实现。

设计目的:通过研究Linux 的进程机制和信号量实现生产者消费者问题的并发控制。

说明:有界缓冲区内设有20个存储单元,放入/取出的数据项设定为1-20这20个整型数。

设计要求:(1)每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容,当前指针位置和生产者/消费者县城的标识符。

(2)生产者和消费者各有两个以上。

(3)多个生产者或多个消费者之间须有共享对缓冲区进行操作的函数代码。

(提示:有界缓冲区可用数组实现)2)设计原理计算机系统中的每个进程都可以消费或生产某类资源。

当系统中某一进程使用某一资源时,可以看作是消耗,且该进程称为消费者。

而当某个进程释放资源时,则它就相当一个生产者。

因为有多个缓冲区,所以生产者线程没有必要在生成新的数据之前等待最后一个数据被消费者线程处理完毕。

同样,消费者线程并不一定每次只能处理一个数据。

在多缓冲区机制下,线程之间不必互相等待形成死锁,因而提高了效率。

多个缓冲区就好像使用一条传送带替代托架,传送带上一次可以放多个产品。

生产者在缓冲区尾加入数据,而消费者则在缓冲区头读取数据。

当缓冲区满的时候,缓冲区就上锁并等待消费者线程读取数据;每一个生产或消费动作使得传送带向前移动一个单位,因而,消费者线程读取数据的顺序和数据产生顺序是相同的。

可以引入一个count计数器来表示已经被使用的缓冲区数量。

用hNotEmptyEvent 和NotFullEvent 来同步生产者和消费者线程。

生产者消费者问题模拟实现(z)

生产者消费者问题模拟实现(z)

int *pcq; //信号量队列指针
} Seamphore;
int producerCongestionQueue[processNum]; //等待信号量 empty
的阻塞队列 int consumerCongestionQueue[processNum]; //等待信
号量 full 的阻塞队列
用信号量机制解决生产者—消费者问题可描述如下:
item B[k];
semaphore empty; empty=k; //可以使用的空缓冲区数
semaphore full; full=0;
//缓冲区内可以使用的产品数
semaphore mutex; mutex=1; //互斥信号量
int in=0; //放入缓冲区指针
号量 s 的阻塞队列中。
(2)V(s):s.value++;若 s.value≤0,则执行 V(s)的进程从等待
信号量 s 的阻塞队列中唤醒头一个进程,然后自己继续执行。若
s.value>0 ,则执行 V(s)
的进程继续执行;
1.2.3 信号量实现互斥
信号量和 PV 操作可用来解决进程互斥问题。为使多个进程能互斥地
append to B[in];
out =
(out+1)%k;
in = (in+1)%k;
V(mutex);
V(mutex);
V(empty);
V(full);
consume();
}
}}
}
Coend
程序中的 P(mutex)和 V(mutex)必须成对出现,夹在两者之间的代码
段是临界区;施加于信号量 empty 和 full 上的 PV 操作也必须成对出

《操作系统概论》实验指导书-实验二 经典的生产者—消费者问题

《操作系统概论》实验指导书-实验二  经典的生产者—消费者问题

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

二、实验内容及要求编制生产者—消费者算法,模拟一个生产者、一个消费者,共享一个缓冲池的情形。

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

生产者-消费者问题是典型的PV操作问题,假设系统中有一个比较大的缓冲池,生产者的任务是只要缓冲池未满就可以将生产出的产品放入其中,而消费者的任务是只要缓冲池未空就可以从缓冲池中拿走产品。

缓冲池被占用时,任何进程都不能访问。

2、每一个生产者都要把自己生产的产品放入缓冲池,每个消费者从缓冲池中取走产品消费。

在这种情况下,生产者消费者进程同步,因为只有通过互通消息才知道是否能存入产品或者取走产品。

他们之间也存在互斥,即生产者消费者必须互斥访问缓冲池,即不能有两个以上的进程同时进行。

三、实验环境操作系统环境:Windows或DOS系统。

编程语言:Turbo C、Visual C++、broland C++、Visual Basic、Delphi、Java等。

四、实验思路和设计1、程序流程图由学生完成。

2、主要程序代码//初始化变量Private Sub Form1_Load(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Loadmutex = 1 //互斥信号量full = 0 //缓冲池中满缓冲区的数量empty = 7 //缓冲池中空缓冲区的数量count1 = 0 //生产的产品数目i = 0End Sub//消费者从缓冲区中消费一个产品Private Sub consumer_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles consumer.ClickIf full > 0 Then //有供消费的缓冲区产品If mutex = 1 Then //申请进入临界区mutex = 0 //消费者已进入互斥临界区labmutex.Text = "0"timer_consumer.Enabled = True //启动消费者消费缓冲区产品Else : MsgBox("缓冲区正被占用,请等待!", 5 + MsgBoxStyle.Exclamation,"信息提示") //不能进入临界区End IfElse : MsgBox("已无可用缓冲区供消费!", 5 + MsgBoxStyle.Exclamation,"信息提示") //无缓冲区产品供消费End IfEnd Sub//生产者向缓冲区中存入一个产品Private Sub producer_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles producer.Clickcount1 = count1 + 1 //生产一个产品If empty > 0 Then //有缓冲区可放产品If mutex = 1 Then //申请进入临界区mutex = 0 //生产者已进入临界区labmutex.Text = "0"timer_production.Enabled = True //启动生产者将产品放入缓冲区Else //不能进入临界区count1 = count1 - 1MsgBox("缓冲区正被占用,请等待!", 7 + MsgBoxStyle.Exc lamation,"信息提示")End IfElse : MsgBox("已无可用缓冲区供存入!", 7 + MsgBoxStyle.Exclamation,"信息提示") //无缓冲区可放产品count1 = count1 - 1End IfEnd Sub//生产者Private Sub timer_production_Tick(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles timer_production.TickIf bool ThenPicture1(count1).Visible = Truelabelshow.Text = "生产者进程正在占用缓冲区,请等待!"bool = FalseElsePicture1(count1).Visible = Falselabelshow.Text = "生产者进程正在占用缓冲区,请等待!"bool = TrueEnd Ifi = i + 1If i = 7 Then //循环缓冲区,首尾相接i = 0timer_production.Enabled = Falsemutex = 1labmutex.Text = "1"Picture1(count1).Visible = Truefull = full + 1labfull.Text = Str(full)empty = empty - 1labempty.Text = Str(empty)labelshow.Text = " Ready "End IfEnd Sub//消费者Private Sub timer_consumer_Tick(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles timer_consumer.TickIf bool ThenLabel1(count1).BackColor = System.Drawing.ColorTranslator.FromOle(&HFF00)labelshow.Text = "消费者进程正在占用缓冲区,请等待!"bool = FalseElseLabel1(count1).BackColor =System.Drawing.ColorTranslator.FromOle(&H8000000F) Picture1(count1).Visible = Falselabelshow.Text = "消费者进程正在占用缓冲区,请等待!"bool = TrueEnd Ifi = i + 1If i = 7 Theni = 0timer_consumer.Enabled = Falsemutex = 1labmutex.Text = "1"Label1(count1).BackColor =System.Drawing.ColorTranslator.FromOle(&H8000000F)Picture1(count1).Visible = Falsecount1 = count1 - 1full = full - 1labfull.Text = Str(full)empty = empty + 1labempty.Text = Str(empty)labelshow.Text = " Ready "End IfEnd Sub3、运行界面和运行结果一般情况下,点一次producer按纽,mutex由1变为0,缓冲区呈现闪烁状态(表示正在存储),此时不可以再进行缓冲区操作,否则将显示“生产者进程正在占用缓冲区,请等待”。

【8A版】C语言编程模拟生产者和消费者问题(附代码程序)

【8A版】C语言编程模拟生产者和消费者问题(附代码程序)

实验三编程模拟生产者和消费者问题一、实验目的和要求模拟实现用同步机构避免发生进程执行时可能出现的与时间有关的错误。

进程是程序在一个数据集合上运行的过程,进程是并发执行的,也即系统中的多个进程轮流地占用处理器运行。

我们把若干个进程都能进行访问和修改的那些变量称为公共变量。

由于进程是并发地执行的,所以,如果对进程访问公共变量不加限制,那么就会产生“与时间有关”的错误,即进程执行后所得到的结果与访问公共变量的时间有关。

为了防止这类错误,系统必须要用同步机构来控制进程对公共变量的访问。

一般说,同步机构是由若干条原语——同步原语——所组成。

本实习要求学生模拟PV操作同步机构的实现,模拟进程的并发执行,了解进程并发执行时同步机构的作用。

二、实验环境Windows操作系统和VisualC++6.0专业版或企业版三、实验步骤模拟PV操作同步机构,且用PV操作解决生产者——消费者问题。

[提示]:(1)PV操作同步机构,由P操作原语和V操作原语组成,它们的定义如下:P操作原语P(s):将信号量s减去1,若结果小于0,则执行原语的进程被置成等待信号量s的状态。

V操作原语V(s):将信号量s加1,若结果不大于0,则释放一个等待信号量s的进程。

这两条原语是如下的两个过程:procedurep(vars:semaphore);begins:=s-1;ifs<0thenW(s)end{p}procedurev(vars:semaphore);egins:=s+1;ifs 0thenR(s)end{v}其中W(s)表示将调用过程的进程置为等待信号量s的状态;R(s)表示释放一个等待信号量s的进程。

在系统初始化时应把semaphore定义为某个类型,为简单起见,在模拟实习中可把上述的semaphore直接改成integer。

(2)生产者——消费者问题。

假定有一个生产者和一个消费者,生产者每次生产一件产品,并把生产的产品存入共享缓冲器以供消费者取走使用。

C语言编程模拟生产者和消费者问题(附代码程序)(2)

C语言编程模拟生产者和消费者问题(附代码程序)(2)

实验三编程模拟生产者和消费者问题一、实验目的和要求模拟实现用同步机构避免发生进程执行时可能出现的与时间有关的错误。

进程是程序在一个数据集合上运行的过程,进程是并发执行的,也即系统中的多个进程轮流地占用处理器运行。

我们把若干个进程都能进行访问和修改的那些变量称为公共变量。

由于进程是并发地执行的,所以,如果对进程访问公共变量不加限制,那么就会产生“与时间有关”的错误,即进程执行后所得到的结果与访问公共变量的时间有关。

为了防止这类错误,系统必须要用同步机构来控制进程对公共变量的访问。

一般说,同步机构是由若干条原语一一同步原语一一所组成。

本实习要求学生模拟PV 操作同步机构的实现,模拟进程的并发执行,了解进程并发执行时同步机构的作用。

二、实验环境Windows操作系统和VisualC++6.0 专业版或企业版三、实验步骤模拟PV操作同步机构,且用PV操作解决生产者一一消费者问题。

[提示]:(1) PV操作同步机构,由P操作原语和V操作原语组成,它们的定义如下:P操作原语P(s):将信号量s减去1,若结果小于0,则执行原语的进程被置成等待信号量s的状态。

V操作原语V(s):将信号量s加1,若结果不大于0,则释放一个等待信号量s的进程。

这两条原语是如下的两个过程:procedurep(vars:semaphore);begi ns:=s-1;ifs<Othe nW(s)en d{p}procedurev(vars:semaphore);egin s:=s+1;ifs -0thenR(s)en d{v}其中W(s)表示将调用过程的进程置为等待信号量s的状态;R(s)表示释放一个等待信号量s的进程。

在系统初始化时应把semaphore定义为某个类型,为简单起见,在模拟实习中可把上述的semaphore 直接改成integer 。

(2) 生产者一一消费者问题。

假定有一个生产者和一个消费者,生产者每次生产一件产品,并把生产的产品存入共享缓冲器以供消费者取走使用。

生产者消费者问题模拟实现(z)

生产者消费者问题模拟实现(z)

生产者-消费者实验1.1实验目的和要求1.1.1实验目的操作系统的基本控制和管理控制都围绕着进程展开,其中的复杂性是由于支持并发和并发机制而引起的。

自从操作系统中引入并发程序设计后,程序的执行不再是顺序的,一个程序未执行完而另一个程序便已开始执行,程序外部的顺序特性消失,程序与计算不再一一对应。

并发进程可能是无关的,也可能是交互的。

然而,交互的进程共享某些变量,一个进程的执行可能会影响其他进程的执行结果,交互的并发进程之间具有制约关系、同步关系。

其中典型模型便是生产者-消费者模型。

本实验通过编写和调试生产者-消费者模拟程序,进一步认识进程并发执行的实质,加深对进程竞争关系,协作关系的理解,掌握使用信号量机制与P、V操作来实现进程的同步与互斥。

1.1.2实验要求1.用高级语言编写一个程序,模拟多个生产者进程和多个消费者进程并发执行,并采用信号量机制与P、V操作实现进程间同步与互斥。

2.撰写实验报告,报告应包含以下内容:(1)实验目的;(2)实验内容;(3)设计思路;(4)程序流程图;(5)程序中主要数据结构和函数说明;(6)带注释的源程序代码;(7)程序运行结果及分析;(8)实验收获与体会。

1.2预备知识1.2.1生产者—消费者问题生产者—消费者问题表述如下:如图所示,有n个生产者和m个消费者,连接在具有k个单位缓冲区的有界环状缓冲上,故又称有界缓冲问题。

生产者不断生成产品,只要缓冲区未满,生产者进程pi所生产的产品就可投入缓冲区;类似的,只要缓冲区非空,消费者进程cj就可以从缓冲区取走并消耗产品。

图生产者—消费者问题示意图著名的生产者—消费者问题(producer-consumer problem)是计算机操作系统中并发进程内在关系的一种抽象,是典型的进程同步问题。

在操作系统中,生产者进程可以是计算进程、发送进程,而消费者进程可以是打印进程、接收进程等,解决好生产者—消费者问题就解决了一类并发进程的同步问题。

操作系统_生产者与消费者问题的实现

操作系统_生产者与消费者问题的实现
shm_unlink("/shm"); /*删除共享内存区,程序中基本上保证了子进程先退出,因此父进程中无wait操作且这部操作放在父进程这里*/
//shmctl(shmid,IPC_RMID,&buf);
//del_sem(semid);
return 0;
}
/*生产者写5次后退出*/
void producer(key_t keyFull, key_t keyEmpty)
empty Write P1 : 2
empty Write P2 : 4
in = 0
Write : 5
full Write V1 : 0
full Write V2 : 0
full Read P2 : 0
out = 0
Read : 5
empty Read V1 : 4
empty Read V2 : 5
Write : 7
full Write V1 : 0
full Write V2 : 0
full Read P2 : 0
out = 2
Read : 7
empty Read V1 : 4
empty Read V2 : 5
Read Finish
p(empty); /*是否有空缓冲区,有则占有,无则被挂起,是原子操作*/
printf("empty Write P2 : %d\n", semctl(empty, 0, GETVAL, 0));
value_write++;
in = in++;
pData[in] = value_write;
in = in % 5;
printf("full Write V2 : %d\n", semctl(full, 0, GETVAL, 0));

C语言编程模拟生产者与消费者问题附代码程序

C语言编程模拟生产者与消费者问题附代码程序

添加标题 添加标题
性能优化总结:在实现过程中,我们采用了多线程和并发等机制,提高了程序的运行效率和响 应速度,同时也考虑了程序的稳定性和可靠性。
展望未来:在未来的工作中,我们可以进一步探索和研究生产者与消费者问题及其解决方案, 例如使用更高级的并发和分布式技术,提高程序的性能和可扩展性。同时,也可以将该问题 及其解决方案应用于其他领域,例如操作系统、网络通信和数据库等。
消费者从共享缓冲区取出数 据的代码示例
消费者从共享缓冲区取出数 据的过程分析
消费者从共享缓冲区取出数 据需要注意的问题
添加同步机制(互斥锁、条件变量)
互斥锁的使用:通过互斥锁可以保证同一时间只有一个线程可以访问 共享资源,避免数据冲突。
条件变量的使用:条件变量可以用于实现线程间的同步,一个线程可 以在条件变量上等待,直到另一个线程发出通知。
代码程序运行结果展 示
第五章
程序运行截图
生产者程序运行截图
消费者程序运行截图
生产者与消费者程序运行截 图
程序运行结果展示
程序运行结果描述
生产者与消费者问题的模拟过程 代码程序的运行结果展示 生产者与消费者问题的解决效果 代码程序的运行效率和性能评估
结果分析
展示代码程序运行结果 分析代码程序的执行过程 解释代码程序对生产者与消费者问题的解决过程 总结代码程序的优缺点及改进方向
创建生产者线程
生产者线程执行逻辑
生产者线程与消费者 线程交互
生产者线程结束
消费者线程代码实现
创建消费者线程
消费者线程调用 生产者线程
消费者线程接收 生产者线程发送 的消息
消费者线程处理 接收到的消息
共享资源代码实现
共享资源定义:共享资源是生产者和消费者共同使用的资源,需要保证 在任何时刻都不会被多个生产者或消费者同时访问

【8A版】C语言编程模拟生产者和消费者问题(附代码程序)

【8A版】C语言编程模拟生产者和消费者问题(附代码程序)

实验三编程模拟生产者和消费者问题一、实验目的和要求模拟实现用同步机构避免发生进程执行时可能出现的与时间有关的错误。

进程是程序在一个数据集合上运行的过程,进程是并发执行的,也即系统中的多个进程轮流地占用处理器运行。

我们把若干个进程都能进行访问和修改的那些变量称为公共变量。

由于进程是并发地执行的,所以,如果对进程访问公共变量不加限制,那么就会产生“与时间有关”的错误,即进程执行后所得到的结果与访问公共变量的时间有关。

为了防止这类错误,系统必须要用同步机构来控制进程对公共变量的访问。

一般说,同步机构是由若干条原语——同步原语——所组成。

本实习要求学生模拟PV操作同步机构的实现,模拟进程的并发执行,了解进程并发执行时同步机构的作用。

二、实验环境Windows操作系统和VisualC++6.0专业版或企业版三、实验步骤模拟PV操作同步机构,且用PV操作解决生产者——消费者问题。

[提示]:(1)PV操作同步机构,由P操作原语和V操作原语组成,它们的定义如下:P操作原语P(s):将信号量s减去1,若结果小于0,则执行原语的进程被置成等待信号量s的状态。

V操作原语V(s):将信号量s加1,若结果不大于0,则释放一个等待信号量s的进程。

这两条原语是如下的两个过程:procedurep(vars:semaphore);begins:=s-1;ifs<0thenW(s)end{p}procedurev(vars:semaphore);egins:=s+1;ifs 0thenR(s)end{v}其中W(s)表示将调用过程的进程置为等待信号量s的状态;R(s)表示释放一个等待信号量s的进程。

在系统初始化时应把semaphore定义为某个类型,为简单起见,在模拟实习中可把上述的semaphore直接改成integer。

(2)生产者——消费者问题。

假定有一个生产者和一个消费者,生产者每次生产一件产品,并把生产的产品存入共享缓冲器以供消费者取走使用。

进程同步模拟设计—生产者和消费者问题

进程同步模拟设计—生产者和消费者问题

课程设计任务书学生姓名:专业班级:指导教师:工作单位:计算机科学与技术学院题目: 进程同步模拟设计——生产者和消费者问题初始条件:1.预备内容:阅读操作系统的进程管理章节内容,对进程的同步和互斥,以及信号量机制度有深入的理解。

2.实践准备:掌握一种计算机高级语言的使用。

要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)1.模拟用信号量机制实现生产者和消费者问题。

2.设计报告内容应说明:⑴课程设计目的与功能;⑵需求分析,数据结构或模块说明(功能与框图);⑶源程序的主要部分;⑷运行结果与运行情况分析;⑸自我评价与总结:i)你认为你完成的设计哪些地方做得比较好或比较出色;ii)什么地方做得不太好,以后如何改正;iii)从本设计得到的收获(在编写,调试,执行过程中的经验和教训);iv)完成本题是否有其他的其他方法(如果有,简要说明该方法);v)对实验题的评价和改进意见,请你推荐设计题目。

时间安排:设计安排一周:周1、周2:完成程序分析及设计。

周2、周3:完成程序调试及测试。

周4、周5:验收、撰写课程设计报告。

(注意事项:严禁抄袭,一旦发现,抄与被抄的一律按0分记)指导教师签名:年月日系主任(或责任教师)签名:年月日进程同步模拟设计——生产者和消费者问题1.模拟用信号量机制实现生产者和消费者问题1.1用信号量机制实现生产者和消费者生产者消费者缓冲区n1.1.1 问题描述:一组生产者向一组消费者提供消息,它们共享一个有界缓冲区n,生产者向其中投放消息,消费者从中取得消息。

1.1.2 规则:①对于生产者进程:产生一个数据,当要送入缓冲区时,要检查缓冲区是否已满,若未满,则可将数据送入缓冲区,并通知消费者进程;否则,等待;②对于消费者进程:当它去取数据时,要看缓冲区中是否有数据可取,若有则取走一个数据,并通知生产者进程,否则,等待。

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

C语言编程模拟生产者和消费者问题(附代码程序)

C语言编程模拟生产者和消费者问题(附代码程序)

C语言编程模拟生产者和消费者问题(附代码程序)实验三编程模拟生产者和消费者问题一、实验目的和要求模拟实现用同步机构避免发生进程执行时可能出现的与时间有关的错误。

进程是程序在一个数据集合上运行的过程,进程是并发执行的,也即系统中的多个进程轮流地占用处理器运行。

我们把若干个进程都能进行访问和修改的那些变量称为公共变量。

由于进程是并发地执行的,所以,如果对进程访问公共变量不加限制,那么就会产生“与时间有关”的错误,即进程执行后所得到的结果与访问公共变量的时间有关。

为了防止这类错误,系统必须要用同步机构来控制进程对公共变量的访问。

一般说,同步机构是由若干条原语一一同步原语一一所组成。

本实习要求学生模拟PV操作同步机构的实现,模拟进程的并发执行,了解进程并发执行时同步机构的作用。

二、实验环境Windows操作系统和VisualC++6.0专业版或企业版三、实验步骤模拟PV操作同步机构,且用PV操作解决生产者一一消费者问题。

[提示]:⑴PV操作同步机构,由P操作原语和V操作原语组成,它们的定义如下:P操作原语P(s):将信号量s减去1,若结果小于0,则执行原语的进程被置成等待信号量s的状态。

V操作原语V(s):将信号量s加1,若结果不大于0,则释放一个等待信号量s的进程。

这两条原语是如下的两个过程:procedurep(vars:semaphore);begi ns:=s-1;ifs<0the nW(s)en d{p}procedurev(vars:semaphore);egin s:=s+1;ifs _Othe nR(s)en d{v}其中W (s)表示将调用过程的进程置为等待信号量s的状态;R (s)表示释放一个等待信号量s的进程。

在系统初始化时应把semaphore定义为某个类型,为简单起见,在模拟实习中可把上述的semaphore直接改成integer。

(2) 生产者一一消费者问题。

假定有一个生产者和一个消费者,生产者每次生产一件产品,并把生产的产品存入共享缓冲器以供消费者取走使用。

编程模拟生产者和消费者问题附代码程序

编程模拟生产者和消费者问题附代码程序

实验三编程模拟生产者和消费者问题一、实验目的和要求模拟实现用同步机构避免发生进程执行时可能出现的与时间有关的错误。

进程是程序在一个数据集合上运行的过程,进程是并发执行的,也即系统中的多个进程轮流地占用处理器运行。

我们把若干个进程都能进行访问和修改的那些变量称为公共变量。

由于进程是并发地执行的,所以,如果对进程访问公共变量不加限制,那么就会产生“与时间有关”的错误,即进程执行后所得到的结果与访问公共变量的时间有关。

为了防止这类错误,系统必须要用同步机构来控制进程对公共变量的访问。

一般说,同步机构是由若干条原语——同步原语——所组成。

本实习要求学生模拟PV操作同步机构的实现,模拟进程的并发执行,了解进程并发执行时同步机构的作用。

二、实验环境Windows操作系统和Visual C++6.0专业版或企业版三、实验步骤模拟PV操作同步机构,且用PV操作解决生产者——消费者问题。

[提示]:(1) PV操作同步机构,由P操作原语和V操作原语组成,它们的定义如下:P操作原语P (s):将信号量s减去1,若结果小于0,则执行原语的进程被置成等待信号量s的状态。

V操作原语V (s):将信号量s加1,若结果不大于0,则释放一个等待信号量s的进程。

这两条原语是如下的两个过程:procedure p (var s: semaphore);begin s: = s-1;if s<0 then W (s)end {p}procedure v (var s: semaphore);egin s: = s+1;if s 0 then R (s)end {v}其中W(s)表示将调用过程的进程置为等待信号量s的状态;R(s)表示释放一个等待信号量s的进程。

在系统初始化时应把semaphore定义为某个类型,为简单起见,在模拟实习中可把上述的semaphore直接改成integer。

(2) 生产者——消费者问题。

假定有一个生产者和一个消费者,生产者每次生产一件产品,并把生产的产品存入共享缓冲器以供消费者取走使用。

C语言编程模拟生产者和消费者问题(附代码程序)

C语言编程模拟生产者和消费者问题(附代码程序)

实验三编程模拟生产者和消费者问题一、实验目的和要求模拟实现用同步机构避免发生进程执行时可能出现的与时间有关的错误。

进程是程序在一个数据集合上运行的过程,进程是并发执行的,也即系统中的多个进程轮流地占用处理器运行。

我们把若干个进程都能进行访问和修改的那些变量称为公共变量。

由于进程是并发地执行的,所以,如果对进程访问公共变量不加限制,那么就会产生“与时间有关”的错误,即进程执行后所得到的结果与访问公共变量的时间有关。

为了防止这类错误,系统必须要用同步机构来控制进程对公共变量的访问。

一般说,同步机构是由若干条原语一一同步原语一一所组成。

本实习要求学生模拟PV操作同步机构的实现,模拟进程的并发执行,了解进程并发执行时同步机构的作用。

二、实验环境Windows操作系统和VisualC++6.0专业版或企业版三、实验步骤模拟PV操作同步机构,且用PV操作解决生产者一一消费者问题。

[提示]:⑴PV操作同步机构,由P操作原语和V操作原语组成,它们的定义如下:P操作原语P(s):将信号量s减去1,若结果小于0,则执行原语的进程被置成等待信号量s的状态。

V操作原语V(s):将信号量s加1,若结果不大于0,则释放一个等待信号量s的进程。

这两条原语是如下的两个过程:procedurep(vars:semaphore);begi ns:=s-1;ifs<0the nW(s)en d{p}procedurev(vars:semaphore);egin s:=s+1;ifs _Othe nR(s)en d{v}其中W (s)表示将调用过程的进程置为等待信号量s的状态;R (s)表示释放一个等待信号量s的进程。

在系统初始化时应把semaphore定义为某个类型,为简单起见,在模拟实习中可把上述的semaphore直接改成integer。

(2) 生产者一一消费者问题。

假定有一个生产者和一个消费者,生产者每次生产一件产品,并把生产的产品存入共享缓冲器以供消费者取走使用。

生产者消费者问题模拟实现(z)

生产者消费者问题模拟实现(z)

生产者-消费者实验1.1实验目的和要求实验目的操作系统的基本控制和管理控制都围绕着进程展开,其中的复杂性是由于支持并发和并发机制而引起的。

自从操作系统中引入并发程序设计后,程序的执行不再是顺序的,一个程序未执行完而另一个程序便已开始执行,程序外部的顺序特性消失,程序与计算不再一一对应。

并发进程可能是无关的,也可能是交互的。

然而,交互的进程共享某些变量,一个进程的执行可能会影响其他进程的执行结果,交互的并发进程之间具有制约关系、同步关系。

其中典型模型便是生产者-消费者模型。

本实验通过编写和调试生产者-消费者模拟程序,进一步认识进程并发执行的实质,加深对进程竞争关系,协作关系的理解,掌握使用信号量机制与P、V操作来实现进程的同步与互斥。

实验要求1.用高级语言编写一个程序,模拟多个生产者进程和多个消费者进程并发执行,并采用信号量机制与P、V操作实现进程间同步与互斥。

2.撰写实验报告,报告应包含以下内容:(1)实验目的;(2)实验内容;(3)设计思路;(4)程序流程图;(5)程序中主要数据结构和函数说明;(6)带注释的源程序代码;(7)程序运行结果及分析;(8)实验收获与体会。

1.2预备知识生产者—消费者问题生产者—消费者问题表述如下:如图3.1所示,有n个生产者和m个消费者,连接在具有k个单位缓冲区的有界环状缓冲上,故又称有界缓冲问题。

生产者不断生成产品,只要缓冲区未满,生产者进程pi所生产的产品就可投入缓冲区;类似的,只要缓冲区非空,消费者进程cj就可以从缓冲区取走并消耗产品。

图 3.1 生产者—消费者问题示意图著名的生产者—消费者问题(producer-consumer problem)是计算机操作系统中并发进程内在关系的一种抽象,是典型的进程同步问题。

在操作系统中,生产者进程可以是计算进程、发送进程,而消费者进程可以是打印进程、接收进程等,解决好生产者—消费者问题就解决了一类并发进程的同步问题。

C语言编程模拟生产者和消费者问题

C语言编程模拟生产者和消费者问题

实验三编程模拟生产者和消费者问题一、实验目的和要求模拟实现用同步机构避免发生进程执行时可能出现的与时间有关的错误。

进程是程序在一个数据集合上运行的过程,进程是并发执行的,也即系统中的多个进程轮流地占用处理器运行。

我们把若干个进程都能进行访问和修改的那些变量称为公共变量。

由于进程是并发地执行的,所以,如果对进程访问公共变量不加限制,那么就会产生“与时间有关” 的错误,即进程执行后所得到的结果与访问公共变量的时间有关。

为了防止这类错误,系统必须要用同步机构来控制进程对公共变量的访问。

一般说,同步机构是由若干条原语——同步原语——所组成。

本实习要求学生模拟PV 操作同步机构的实现,模拟进程的并发执行,了解进程并发执行时同步机构的作用。

二、实验环境Windows操作系统和Visual C++专业版或企业版三、实验步骤模拟PV 操作同步机构,且用PV 操作解决生产者——消费者问题。

[提示]:⑴PV操作同步机构,由P操作原语和V操作原语组成,它们的定义如下:P操作原语P (s):将信号量s减去1,若结果小于0,则执行原语的进程被置成等待信号量s 的状态。

V操作原语V (s):将信号量s加1,若结果不大于0,则释放一个等待信号量s 的进程。

这两条原语是如下的两个过程:procedure p (var s: semaphore);begin s: = s-1;if s<0 then W (s)end {p}procedure v (var s: semaphore);egin s: = s+1;if s£ 0 then R (s) end {v}其中W (s)表示将调用过程的进程置为等待信号量s的状态;R (s)表示释放一个等待信号量s的进程。

在系统初始化时应把semaphore定义为某个类型,为简单起见,在模拟实习中可把上述的semaphore直接改成integer。

(2) 生产者——消费者问题。

C语言编程模拟生产者和消费者问题(附代码程序)

C语言编程模拟生产者和消费者问题(附代码程序)

假定缓冲器内可同时存放 10 件产品。那么,用 PV 操作来实现生产者和消费者 之间的同步,生产者和消费者两个进程的程序如下:
B: array [0..9] of products;
s1, s2; semaphore;
s1: =10, s2: =0;
IN, out:
图 3-2 模拟的处理器指令
生产者程序 produce p (s1) PUT v (s2) goto 0
图 3-3 生产者和消费者程序
消费者程序 p (s2) GET v (s1)
consume goto 0
(5) 程序设计 本实习中的程序由三部分组成:初始化程序、处理器调度程序、模拟处理器 指令执行程序。各部分程序的功能及相互间的关系由图 3-4 至图 3-7 指出。
图 3-4 初始化流程
图 3-5 模拟处理器调度
相应的过程执行。
模拟的指令
功能
p (s) v (s) put GET produce consume GOTO L NOP
序号 0 1 2 3 4
执行 P 操作原语 执行 V 操作原语 B[IN]: =product; IN: = (IN+1) mod 10 x: =B[out]; out: =(out+1) mod 10 输入一个字符放入 C 中 打印或显示 x 中的字符 PC: =L 空操作
因是为等待信号量 s1 或 s2);当进程处于等待态或就绪态时,PCB 中保留了断
点信息,一旦进程再度占有处理器则就从断点位置继续运行;当进程处于完成状
态,表示进程执行结束。
进程名 状态 等待原因 断点
图 3-1 进程控制块结构
(4) 处理器的模拟。
计算机硬件提供了一组机器指令,处理器的主要职责是解释执行机器指令。

C语言编程模拟生产者和消费者问题(附代码程序)(2)

C语言编程模拟生产者和消费者问题(附代码程序)(2)

实验三编程模拟生产者和消费者问题一、实验目的和要求模拟实现用同步机构避免发生进程执行时可能出现的与时间有关的错误。

进程是程序在一个数据集合上运行的过程,进程是并发执行的,也即系统中的多个进程轮流地占用处理器运行。

我们把若干个进程都能进行访问和修改的那些变量称为公共变量。

由于进程是并发地执行的,所以,如果对进程访问公共变量不加限制,那么就会产生“与时间有关”的错误,即进程执行后所得到的结果与访问公共变量的时间有关。

为了防止这类错误,系统必须要用同步机构来控制进程对公共变量的访问。

一般说,同步机构是由若干条原语一一同步原语一一所组成。

本实习要求学生模拟PV 操作同步机构的实现,模拟进程的并发执行,了解进程并发执行时同步机构的作用。

二、实验环境Windows操作系统和VisualC++6.0 专业版或企业版三、实验步骤模拟PV操作同步机构,且用PV操作解决生产者一一消费者问题。

[提示]:(1) PV操作同步机构,由P操作原语和V操作原语组成,它们的定义如下:P操作原语P(s):将信号量s减去1,若结果小于0,则执行原语的进程被置成等待信号量s的状态。

V操作原语V(s):将信号量s加1,若结果不大于0,则释放一个等待信号量s的进程。

这两条原语是如下的两个过程:procedurep(vars:semaphore);begi ns:=s-1;ifs<Othe nW(s)en d{p}procedurev(vars:semaphore);egin s:=s+1;ifs -0thenR(s)en d{v}其中W(s)表示将调用过程的进程置为等待信号量s的状态;R(s)表示释放一个等待信号量s的进程。

在系统初始化时应把semaphore定义为某个类型,为简单起见,在模拟实习中可把上述的semaphore 直接改成integer 。

(2) 生产者一一消费者问题。

假定有一个生产者和一个消费者,生产者每次生产一件产品,并把生产的产品存入共享缓冲器以供消费者取走使用。

实验5 模拟生产者-消费者实验

实验5 模拟生产者-消费者实验

实验5 模拟生产者-消费者实验
实验目的
(1)掌握信号量及互斥信号量的使用方法;
(2)掌握共享存储区的使用方法。

实验原理
生产者-消费者(producer-consumer)问题是一个著名的进程同步问题。

它描述的是:有一群生产者进程在生产产品,并将这些产品提供给消费者进程去消费。

为使生产者进程与消费者进程能并发执行,在两者之间设置了一个具有n个缓冲区的缓冲池,生产者进程将它所生产的产品放入一个缓冲区中;消费者进程可从一个缓冲区中取走产品去消费。

尽管所有的生产者进程和消费者进程都是以异步方式运行的,但它们之间必须保持同步,即不允许消费者进程到一个空缓冲区去取产品;也不允许生产者进程向一个已装满产品且尚未被取走的缓冲区中投放产品。

为了保证数据的一致性,必须将信号量机制引入到生产者-消费者问题之中。

对于n个缓冲区,设置互斥信号量mutex使诸进程实现对缓冲池的互斥使用;利用资源信号量empty和full分别表示缓冲池中空缓冲区和满缓冲区的数量。

又假设生产者和消费者进程相互等效,只要缓冲池未满,生产者便可将消息送入缓冲池;只要缓冲池未空,消费者便可从缓冲池中取走一个消息。

6.4 实验内容
模拟生产者-消费者工作机制,由串口接收任务不断接收用户从超级终端输入的数据,模拟成数据的生产者,并将数据存放到共享缓冲区中;由LCD任务不断从共享缓冲区中读取数据,并显示出来,模拟成消费者。

C语言编程模拟生产者和消费者问题(附代码程序)

C语言编程模拟生产者和消费者问题(附代码程序)

实验三编程模拟生‎产者和消费‎者问题一、实验目的和‎要求模拟实现用‎同步机构避‎免发生进程‎执行时可能‎出现的与时‎间有关的错‎误。

进程是程序‎在一个数据‎集合上运行‎的过程,进程是并发‎执行的,也即系统中‎的多个进程‎轮流地占用‎处理器运行‎。

我们把若干‎个进程都能‎进行访问和‎修改的那些‎变量称为公‎共变量。

由于进程是‎并发地执行‎的,所以,如果对进程‎访问公共变‎量不加限制‎,那么就会产‎生“与时间有关‎”的错误,即进程执行‎后所得到的‎结果与访问‎公共变量的‎时间有关。

为了防止这‎类错误,系统必须要‎用同步机构‎来控制进程‎对公共变量‎的访问。

一般说,同步机构是‎由若干条原‎语——同步原语——所组成。

本实习要求‎学生模拟P‎V操作同步‎机构的实现‎,模拟进程的‎并发执行,了解进程并‎发执行时同‎步机构的作‎用。

二、实验环境Windo‎w s操作系‎统和Vis‎u al C++6.0专业版或‎企业版三、实验步骤模拟PV操‎作同步机构‎,且用PV操‎作解决生产‎者——消费者问题‎。

[提示]:(1) PV操作同‎步机构,由P操作原‎语和V操作‎原语组成,它们的定义‎如下:P操作原语‎P (s):将信号量s‎减去1,若结果小于‎0,则执行原语‎的进程被置‎成等待信号‎量s的状态‎。

V操作原语‎V (s):将信号量s‎加1,若结果不大‎于0,则释放一个‎等待信号量‎s的进程。

这两条原语‎是如下的两‎个过程:proce‎d ure p (var s: semap‎h ore);begin‎s: = s-1;if s<0 then W (s)end {p}proce‎d ure v (var s: semap‎h ore);egin s: = s+1;if s 0 then R (s)end {v}其中W(s)表示将调用‎过程的进程‎置为等待信‎号量s的状‎态;R(s)表示释放一‎个等待信号‎量s的进程‎。

【8A版】C语言编程模拟生产者和消费者问题(附代码程序)

【8A版】C语言编程模拟生产者和消费者问题(附代码程序)

实验三编程模拟生产者和消费者问题一、实验目的和要求模拟实现用同步机构避免发生进程执行时可能出现的与时间有关的错误。

进程是程序在一个数据集合上运行的过程,进程是并发执行的,也即系统中的多个进程轮流地占用处理器运行。

我们把若干个进程都能进行访问和修改的那些变量称为公共变量。

由于进程是并发地执行的,所以,如果对进程访问公共变量不加限制,那么就会产生“与时间有关”的错误,即进程执行后所得到的结果与访问公共变量的时间有关。

为了防止这类错误,系统必须要用同步机构来控制进程对公共变量的访问。

一般说,同步机构是由若干条原语——同步原语——所组成。

本实习要求学生模拟PV操作同步机构的实现,模拟进程的并发执行,了解进程并发执行时同步机构的作用。

二、实验环境Windows操作系统和VisualC++6.0专业版或企业版三、实验步骤模拟PV操作同步机构,且用PV操作解决生产者——消费者问题。

[提示]:(1)PV操作同步机构,由P操作原语和V操作原语组成,它们的定义如下:P操作原语P(s):将信号量s减去1,若结果小于0,则执行原语的进程被置成等待信号量s的状态。

V操作原语V(s):将信号量s加1,若结果不大于0,则释放一个等待信号量s的进程。

这两条原语是如下的两个过程:procedurep(vars:semaphore);begins:=s-1;ifs<0thenW(s)end{p}procedurev(vars:semaphore);egins:=s+1;ifs 0thenR(s)end{v}其中W(s)表示将调用过程的进程置为等待信号量s的状态;R(s)表示释放一个等待信号量s的进程。

在系统初始化时应把semaphore定义为某个类型,为简单起见,在模拟实习中可把上述的semaphore直接改成integer。

(2)生产者——消费者问题。

假定有一个生产者和一个消费者,生产者每次生产一件产品,并把生产的产品存入共享缓冲器以供消费者取走使用。

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

操作系统课程设计报告专业计算机科学与技术学生姓名郑伟班级BM计算机091 学号0951401123指导教师李先锋完成日期2011年12月31日博雅学院题目:生产者与消费者问题的模拟实现一、设计目的本课程设计是学习完“操作系统原理”课程后进行的一次全面的综合训练,通过课程设计,更好地掌握操作系统的原理及实现方法,加深对操作系统基础理论和重要算法的理解,加强学生的动手能力。

二、设计内容1)概述用多进程同步方法解决生产者-消费者问题,C或C++语言实现。

设计目的:通过研究Linux 的进程机制和信号量实现生产者消费者问题的并发控制。

说明:有界缓冲区内设有20个存储单元,放入/取出的数据项设定为1-20这20个整型数。

设计要求:(1)每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的全部内容,当前指针位置和生产者/消费者县城的标识符。

(2)生产者和消费者各有两个以上。

(3)多个生产者或多个消费者之间须有共享对缓冲区进行操作的函数代码。

(提示:有界缓冲区可用数组实现)2)设计原理计算机系统中的每个进程都可以消费或生产某类资源。

当系统中某一进程使用某一资源时,可以看作是消耗,且该进程称为消费者。

而当某个进程释放资源时,则它就相当一个生产者。

因为有多个缓冲区,所以生产者线程没有必要在生成新的数据之前等待最后一个数据被消费者线程处理完毕。

同样,消费者线程并不一定每次只能处理一个数据。

在多缓冲区机制下,线程之间不必互相等待形成死锁,因而提高了效率。

多个缓冲区就好像使用一条传送带替代托架,传送带上一次可以放多个产品。

生产者在缓冲区尾加入数据,而消费者则在缓冲区头读取数据。

当缓冲区满的时候,缓冲区就上锁并等待消费者线程读取数据;每一个生产或消费动作使得传送带向前移动一个单位,因而,消费者线程读取数据的顺序和数据产生顺序是相同的。

可以引入一个count计数器来表示已经被使用的缓冲区数量。

用hNotEmptyEvent 和NotFullEvent 来同步生产者和消费者线程。

每当生产者线程发现缓冲区满( count=BufferSize ),它就等待hNotEmptyEvent 事件。

同样,当消费者线程发现缓冲区空,它就开始等待hNotEmptyEvent。

生产者线程写入一个新的数据之后,就立刻发出hNotEmptyEvent 来唤醒正在等待的消费者线程;消费者线程在读取一个数据之后,就发出hNotFullEvent 来唤醒正在等待的生产者线程。

通过一个有界缓冲区(用数组来实现,类似循环队列)把生产者和消费者联系起来。

假定生产者和消费者的优先级是相同的,只要缓冲区未满,生产者就可以生产产品并将产品送入缓冲区。

类似地,只要缓冲区未空,消费者就可以从缓冲区中去走产品并消费它。

应该禁止生产者向满的缓冲区送入产品,同时也应该禁止消费者从空的缓冲区中取出产品,这一机制有生产者线程和消费者线程之间的互斥关系来实现。

为解决生产者/消费者问题,应该设置两个资源信号量,其中一个表示空缓冲区的数目,用g_hFullSemaphore表示,其初始值为有界缓冲区的大小SIZE_OF_BUFFER;另一个表示缓冲区中产品的数目,用g_hEmptySemaphore表示,其初始值为0。

另外,由于有界缓冲区是一个临界资源,必须互斥使用,所以还需要再设置一个互斥信号量g_hMutex,起初值为1。

在生产者/消费者问题中,信号量实现两种功能。

首先,它是生产产品和消费产品的计数器,计数器的初始值是可利用的资源数目(有界缓冲区的长度)。

其次,它是确保产品的生产者和消费者之间动作同步的同步器。

生产者要生产一个产品时,首先对资源信号量g_hFullSemaphore和互斥信号量g_hMutex进行P操作,申请资源。

如果可以通过的话,就生产一个产品,并把产品送入缓冲区。

然后对互斥信号量g_hMutex和资源信号量g_hEmptySemaphore进行V操作,释放资源。

消费者要消费一个产品时,首先对资源信号量g_hEmptySemaphore和互斥信号量g_hMutex进行P操作,申请资源。

如果可以通过的话,就从缓冲区取出一个产品并消费掉。

然后对互斥信号量g_hMutex和资源信号量g_hFullSemaphore 进行V操作,释放资源。

如果缓冲区中已经没有可用资源,就把申请资源的进程添加到等待队列的队尾。

如果有一个资源被释放,在等待队列中的第一个进程被唤醒并取得这个资源的使用权。

数据结构及信号量定义的说明;#define Size 20struct huan{int isHave; //标记缓冲区是否有内容,有内容时,消费者才可以使用,//没内容时,生产者才可以往缓冲区内写东西 //0表示没有内容,1表示有内容int jud; //标志缓冲区是否在被使用中,0代表未被使用,1表示使用中int context; //缓冲的内容};描叙生产者或消费者:struct person{int end; //记录是否完成任务,0表示完成,1表示未完成任务char * name; /*线程名*/pthread_t thread; /*线程句柄*/};4)结果及分析1、运行示例在c++中运行源程序,程序主界面截图:按回车及申请资源和缓冲区进行p操作和申请互斥信号量。

按回车后截图,开始生产产品,产品数量增加1,缓冲区中产品数量也增加1当产品数量超过4时则停止生产执行v操作,进行消费者生产线程,即开始消费一个产品,当消费了一个产品时产品数量小于4则将消费者线程惊醒v操作开始生产者线程,如此循环,当用户按回车后这对所有的线程进行v操作,即停止所有的操作。

分析:生产者线程和消费者线程是2个互斥量,即2个线程只能有一进行操作,生产的产品的数量不能超过4个当小于4时择进行消费者线程。

5)设计小结在生产者与消费者问题的算法编写程序的时候要尽可能用全所学到的函数,因为这是检测我们用C语言进行程序设计的能力的重要方式。

在编写程序的时候我们不可能一次就成功,往往一个图形要修改甚至是十几次数据才能得到预期的结果。

因此在编写程序的时候一定不能急躁,要耐心地检测输入的数据和输出的结果,在没达到预期目的的情况下,要及时修改数据进行下一次的检测,只有这样才能成功地用C语言编写出需要的程序。

编写程序是一个长期的过程,因此不能急躁,要坐的住。

由于对C语言知识已经有些遗忘,所以我找出了以前的笔记,花了半天的时间去回忆和理解。

对操作系统有关消费者---生产者问题的含义也已经有点模糊,我花了一天的时间看教材,还到图书馆借阅了相关的资料,才开始编程。

刚开始对如何动态实现消费者---生产者问题一筹莫展,于是和一些同学就这个问题讨论过,但是没什么好的效果。

编写程序有的时候需要的就是灵感,因此当有灵感的时候就要开始做,而不能等,必须在灵感未消失前付诸行动,所以才有了凌晨两点才最后做完大型作业。

虽然很累,但是觉得值得。

6)参考文献【1】汤子瀛等.计算机操作系统.西安电子科技大学出版社.2007年2月【2】张尧学等编著,计算机操作系统教程,清华出版社。

2002.2 【3】严蔚敏,吴伟民编著,数据结构,清华大学出版社。

2002【4】陈向群编著,操作系统教程,北京大学出版社,2001.07【5】郑莉等编著,C++语言设计。

北京:清华大学出版社.2000三、附录(源程序)#include <windows.h>#include <iostream>const unsigned short SIZE_OF_BUFFER = 20;//有界缓冲区长度int g_buffer[SIZE_OF_BUFFER];//开辟缓冲区,用数组表示,可以看成是一个循环队列unsigned short ProductID = 0;//新生产出来的产品的产品号unsigned short ConsumeID = 0;//被消耗的产品的产品号unsigned short in = 0;//产品进缓冲区时的缓冲区下标,用于记录生产者的指针位置unsigned short out = 0;//产品出缓冲区时的缓冲区下标,用于记录消费者的指针位置bool g_continue = 1;//控制程序运行:1表示继续运行,0表示停止运行HANDLE g_hMutex;//线程间的互斥信号量HANDLE g_hFullSemaphore;//资源信号量:缓冲区满HANDLE g_hEmptySemaphore;//资源信号量:缓冲区空DWORD WINAPI Producer(LPVOID);//生产者线程DWORD WINAPI Consumer(LPVOID);//消费者线程const unsigned short PRODUCERS_COUNT=4;//生产者的个数const unsigned short CONSUMERS_COUNT=3;//消费者的个数const unsigned short THREADS_COUNT=PRODUCERS_COUNT+CONSUMERS_COUNT;//总线程数HANDLE hThreads[PRODUCERS_COUNT];//各线程的handleDWORD producerID[CONSUMERS_COUNT];//生产者线程的标识符DWORD consumerID[THREADS_COUNT];//消费者线程的标识符/*----------------------------程序提示信息开始------------------------------*/void info()//程序提示信息{std::cout<<"* - - - - - - - - - - - - - - - - - - - - - - - *"<<std::endl;std::cout<<"| 题目:生产者消费者问题|"<<std::endl;std::cout<<"| 指导老师:李先锋|"<<std::endl;std::cout<<"| 作者:郑伟|"<<std::endl;std::cout<<"| 代码行数:200+ |"<<std::endl;std::cout<<"| 班级:BM计算机091 |"<<std::endl;std::cout<<"| 完成日期:2011-12-30 |"<<std::endl;std::cout<<"* - - - - - - - - - - - - - - - - - - - - - - - *"<<std::endl;std::cout<<std::endl<<"按回车键继续";getchar();}/*----------------------------程序提示信息结束------------------------------*//*----------------------------生产一个产品开始------------------------------*/ //生产一个产品,输出其ID号void Produce(){std::cout<<std::endl;std::cerr<<"生产一个产品: "<<++ProductID;std::cout<<std::endl;}/*----------------------------生产一个产品结束------------------------------*//*----------------------把新生产的产品放入缓冲区开------------------------*/ //把新生产的产品放入缓冲区void Append(){std::cerr<<"把生产的产品送入缓冲区";g_buffer[in]=ProductID;in=(in+1)%SIZE_OF_BUFFER;std::cerr<<std::endl;std::cout<<"缓冲区产品生产者/消费者"<<std::endl;//新产品放入缓冲区后,输出缓冲区当前的状态for(int i=0;i<SIZE_OF_BUFFER;++i){//输出缓冲区下标if (i<10)std::cout<<i<<" "<<g_buffer[i];elsestd::cout<<i<<" "<<g_buffer[i];if(i==in){if(g_buffer[i]<10)std::cout<<" ";elsestd::cout<<" ";std::cout<<" <-- 生产者";//输出生产者的指针位置}if(i==out){if(g_buffer[i]<10)std::cout<<" ";elsestd::cout<<" ";std::cout<<" <-- 消费者";//输出消费者的指针位置}std::cout<<std::endl;}}/*----------------------把新生产的产品放入缓冲区结------------------------*/ /*----------------------------消费一个产品开始------------------------------*/ void Consume()//消费一个产品{std::cout<<std::endl;std::cerr<<"消费一个产品: "<<ConsumeID;std::cout<<std::endl;}/*----------------------------消费一个产品结束------------------------------*//*-----------------------从缓冲区中取出一个产品开始-------------------------*/ //从缓冲区中取出一个产品void Take(){std::cout<<std::endl;std::cerr<<"从缓冲区取出一个产品";ConsumeID=g_buffer[out];out=(out+1)%SIZE_OF_BUFFER;std::cerr<<std::endl;std::cout<<std::endl;std::cout<<"缓冲区产品生产者/消费者"<<std::endl;//取出一个产品后,输出缓冲区当前的状态for(int i=0;i<SIZE_OF_BUFFER;++i){//输出缓冲区下标if(i<10)std::cout<<i<<" "<<g_buffer[i];elsestd::cout<<i<<" "<<g_buffer[i];if(i==in){if(g_buffer[i]<10)std::cout<<" ";elsestd::cout<<" ";std::cout<<" <-- 生产者";//输出生产者的指针位置}if(i==out){if(g_buffer[i]<10)std::cout<<" ";elsestd::cout<<" ";std::cout<<" <-- 消费者";//输出消费者的指针位置}std::cout<<std::endl;}}/*-----------------------从缓冲区中取出一个产品结束-------------------------*/ /*-----------------------------生产者线程开始-------------------------------*///生产者线程DWORD WINAPI Producer(LPVOID lpPara){while(g_continue){//资源信号量的P操作WaitForSingleObject(g_hFullSemaphore,INFINITE);//互斥信号量的P操作WaitForSingleObject(g_hMutex,INFINITE);//生产一个产品Produce();//把新生产的产品放入缓冲区Append();Sleep(2000);//互斥信号量的V操作ReleaseMutex(g_hMutex);//资源信号量的V操作ReleaseSemaphore(g_hEmptySemaphore,1,NULL);}return 0;}/*-----------------------------生产者线程结束-------------------------------*//*-----------------------------消费者线程开始-------------------------------*/ //消费者线程DWORD WINAPI Consumer(LPVOID lpPara){while(g_continue){//资源信号量的P操作WaitForSingleObject(g_hEmptySemaphore,INFINITE);//互斥信号量的P操作WaitForSingleObject(g_hMutex,INFINITE);//从缓冲区中取出一个产品Take();//消费一个产品Consume();Sleep(2000);//互斥信号量的V操作ReleaseMutex(g_hMutex);//资源信号量的V操作ReleaseSemaphore(g_hFullSemaphore,1,NULL);}return 0;}/*-----------------------------消费者线程结束-------------------------------*//*---------------------------创建生产者线程开始-----------------------------*/void createPT()//创建生产者线程{for(int i=0;i<PRODUCERS_COUNT;++i){hThreads[i]=CreateThread(NULL,0,Producer,NULL,0,&producerID[i]);if(hThreads[i]==NULL)g_continue=0;}}/*---------------------------创建生产者线程结束-----------------------------*//*---------------------------创建消费者线程开始-----------------------------*/void createCT()//创建消费者线程{for (int j=0;j<CONSUMERS_COUNT;++j){hThreads[PRODUCERS_COUNT+j]=CreateThread(NULL,0,Consumer,NULL,0,&consume rID[j]);if (hThreads[j]==NULL)g_continue=0;}}/*---------------------------创建消费者线程结束-----------------------------*//*-------------------------------主函数开始---------------------------------*/int main(){//显示程序提示信息info();//创建互斥信号量g_hMutex=CreateMutex(NULL,FALSE,NULL);//创建资源信号量g_hFullSemaphore=CreateSemaphore(NULL,SIZE_OF_BUFFER-1,SIZE_OF_BUFFER-1, NULL);g_hEmptySemaphore=CreateSemaphore(NULL,0,SIZE_OF_BUFFER-1,NULL);//创建生产者线程createPT();//创建消费者线程createCT();//不按回车键的话程序会一直运行下去while(g_continue)//按回车键终止程序if(getchar())g_continue = 0;}。

相关文档
最新文档