本篇文章给大家谈谈操作系统生产者消费者问题,以及操作系统生产者消费者问题课程设计对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
今天给各位分享操作系统生产者消费者问题的知识,其中也会对操作系统生产者消费者问题课程设计
进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
操作系统 关于生产者消费者的问题
empty是资源信号量
操作系统生产者消费者问题,意思生产者、消费者都靠这个信号量来进行生产、消费。
为什么“生产者进程向n个缓冲区投满产品后消费者进程才开始从中取产品”
操作系统生产者消费者问题?
其实可以转为问进程间为什么需要
同步、互斥?您对这问题的研究不够请再看书。
这里
操作系统生产者消费者问题我和您举个例子。
信号量的目的是管理生产者、消费者对公共资源(缓冲区)的访问
p原语对资源进行占有
操作系统生产者消费者问题,V原语对资源进行释放
缺少empty资源信号量,那么只有互斥信号量。
但是empty和FUll需要成对出现,就算缺少signal(empty),那么消费者没对empty信号进行释放,产生的结果只会是下次生产者想进去生产东西但因为信号量缺失,进不去。
我也很想知道为什么“生产者进程向n个缓冲区投满产品后消费者进程才开始从中取产品”?
计算机操作系统生产者消费者
生产者-消费者是一种设计模式。生产者往缓冲区写入
数据操作系统生产者消费者问题,消费者从缓冲区拿取数据
操作系统生产者消费者问题,两者通过缓冲区来进行通信。这样
操作系统生产者消费者问题的话生产者不必担心要等待消费者使用完数据,消费者也不用担心不够时间处理完所有数据。
关于计算机操作系统 生产者和消费者问题 哪位来解答一下
wait(x)是把x这个信号量进入临界区
操作系统生产者消费者问题,
signal(y)是把y这个信号量离开临界区。
此题中
操作系统生产者消费者问题,wait顺序不可变,signal可变。
进入临界区
操作系统生产者消费者问题的话,其他线程再申请进入同一个信号量
操作系统生产者消费者问题的临界区就会block,等待。。
1)wait顺序不可逆原因:
对于消费者,这里先wait(full)是为了确保full不是0(即确保可以消费),不然先wait(mutex)的话,如果full为0,就会一直停在这里,等待消费。然后生产者就一直在等待进入mutex而无法进行生产,导致死锁。
对于生产者也是如此。
2)signal可逆原因:
对生产者,因为已经生产完了,所以先退出mutex临界区或者或者对full的数目加一,都不会产生影响。
设full=0,此时消费者无法进入full临界区,如果先signal(full),那么full数目加1,消费者可以进入full临界区,但是metux还被生产者使用,所以消费之要等到生产者signal(mutex)才能进入,没有任何影响。
对于消费者也是如此。
操作系统 判断题 生产者消费者问题
一、明确定义
要理解生产消费者问题,首先应弄清PV操作的含义:PV操作是由P操作原语和V操作原语组成(原语是不可中断的过程),对信号量进行操作,具体定义如下:
P(S):①将信号量S的值减1,即S=S-1;
②如果S³0,则该进程继续执行;否则该进程置为等待状态,排入等待队列。
V(S):①将信号量S的值加1,即S=S+1;
②如果S0,则该进程继续执行;否则释放队列中第一个等待信号量的进程。
这只是书本的定义,对于这部分内容,老师先不要急于解释上面的
程序流程,而是应该让学生首先知道P操作与V操作到底有什么作用。
P操作相当于申请资源,而V操作相当于释放资源。所以要学生记住以下几个关键字:
P操作-----à申请资源
V操作----à释放资源
二、形象启发
为此举两个生活中的例子:
例一:在公共电话厅打电话
公共电话厅里有多个电话,如某人要打电话,首先要进行申请,看是否有电话空闲,若有,则可以使用电话,如果电话亭里所有电话都有人正在使用,那后来的人只有排队等候。当某人用完电话后,则有空电话腾出,正在排队的第一个人就可以使用电话。这就相当于PV操作:
某人要打电话,首先要进行申请,相当于执行一次P操作,申请一个可用资源(电话);
某人用完电话,则有空电话腾出,相当于执行一次V操作,释放一个可用资源(电话)。
在多媒体课件中,这部分内容充分通过动画效果,演示整个申请电话资源(P操作)与释放电话资源(V操作)的过程,同时显示当前可用的资源个数(电话个数)。课件直观生动,一目了然,学生非常容易接受,并且理解深刻。
三、分层解剖
在理解了PV操作的的含义后,就必须讲解利用PV操作可以实现进程的两种情况:互斥和同步。根据互斥和同步不同的特点,就有利用PV操作实现互斥与同步相对固定的结构模式。这里就不详细讲解了。但生产者-消费者问题是一个有代表性的进程同步问题,要学生透彻理解并不容易。但是如果我们将问题细分成三种情况进行讲解,理解难度将大大降低。
1)一个生产者,一个消费者,公用一个缓冲区。
可以作以下比喻:将一个生产者比喻为一个生产厂家,如伊利牛奶厂家,而一个消费者,比喻是学生小明,而一个缓冲区则比喻成一间好又多。第一种情况,可以理解成伊利牛奶生产厂家生产一盒牛奶,把它放在好又多一分店进行销售,而小明则可以从那里买到这盒牛奶。只有当厂家把牛奶放在商店里面后,小明才可以从商店里买到牛奶。所以很明显这是最简单的同步问题。
解题如下:
定义两个同步信号量:
empty——表示缓冲区是否为空,初值为1。
full——表示缓冲区中是否为满,初值为0。
生产者进程
while(TRUE){
生产一个产品;
P(empty);
产品送往Buffer;
V(full);
}
消费者进程
while(TRUE){
P(full);
从Buffer取出一个产品;
V(empty);
消费该产品;
2)一个生产者,一个消费者,公用n个环形缓冲区。
第二种情况可以理解为伊利牛奶生产厂家可以生产好多牛奶,并将它们放在多个好又多分店进行销售,而小明可以从任一间好又多分店中购买到牛奶。同样,只有当厂家把牛奶放在某一分店里,小明才可以从这间分店中买到牛奶。不同于第一种情况的是,第二种情况有N个分店(即N个缓冲区形成一个环形缓冲区),所以要利用指针,要求厂家必须按一定的顺序将商品依次放到每一个分店中。缓冲区的指向则通过模运算得到。
解题如下:
定义两个同步信号量:
empty——表示缓冲区是否为空,初值为n。
full——表示缓冲区中是否为满,初值为0。
设缓冲区的编号为1~n-1,定义两个指针in和out,分别是生产者进程和消费者进程使用的指针,指向下一个可用的缓冲区。
生产者进程
while(TRUE){
生产一个产品;
P(empty);
产品送往buffer(in);
in=(in+1)mod n;
V(full);
}
消费者进程
while(TRUE){
P(full);
从buffer(out)中取出产品;
out=(out+1)mod n;
V(empty);
消费该产品;
}
3)一组生产者,一组消费者,公用n个环形缓冲区
第三种情况,可以理解成有多间牛奶生产厂家,如蒙牛,达能,光明等,消费者也不只小明一人,有许许多多消费者。不同的牛奶生产厂家生产的商品可以放在不同的好又多分店中销售,而不同的消费者可以去不同的分店中购买。当某一分店已放满某个厂家的商品时,下一个厂家只能把商品放在下一间分店。所以在这种情况中,生产者与消费者存在同步关系,而且各个生产者之间、各个消费者之间存在互斥关系,他们必须互斥地访问缓冲区。
解题如下:
定义四个信号量:
empty——表示缓冲区是否为空,初值为n。
full——表示缓冲区中是否为满,初值为0。
mutex1——生产者之间的互斥信号量,初值为1。
mutex2——消费者之间的互斥信号量,初值为1。
设缓冲区的编号为1~n-1,定义两个指针in和out,分别是生产者进程和消费者进程使用的指针,指向下一个可用的缓冲区。
生产者进程
while(TRUE){
生产一个产品;
P(empty);
P(mutex1);
产品送往buffer(in);
in=(in+1)mod n;
V(mutex1);
V(full);
}
消费者进程
while(TRUE){
P(full);
P(mutex2);
从buffer(out)中取出产品;
out=(out+1)mod n;
V(mutex2);
V(empty);
PV操作经典问题
PV(wait/singal)在考操作系统的时候经常被问到,这篇小文就整理一下几个常见的PV问题。
假定在生产者和消费者之间的公用缓冲池中,具有n个缓冲区,这时可利用互斥信号量mutex实现诸进程对缓冲池的互斥使用。利用信号量empty和full分别表示缓冲池中空缓冲区和满缓冲区的数量。
又假定这些生产者和消费者相互等效,只要缓冲池未满,生产者便可以将消息送入缓冲池;只要缓冲池未空,消费者便可以从缓冲池取走一个信息。
对生产者和消费者问题可以描述如下:
该问题是描述有五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五只筷子和五个碗,他们的生活方式是交替地进行思考和进餐。平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有他拿到两只筷子的时候才能进行进餐。进餐完毕,放下筷子继续思考。
这是使用AND机制的信号量处理。
操作系统中生产者消费者问题。(c++)
#include <windows.h
#include <iostream.h
#include<stdio.h
#include<stdlib.h
const unsigned short SIZE_OF_BUFFER = 10; //缓冲区长度
unsigned short ProductID = 0; //产品号
unsigned short ConsumeID = 0; //将被消耗的产品号
unsigned short in = 0; //产品进缓冲区时的下标
unsigned short out = 0; //产品出缓冲区时的下标
int g_buffer[SIZE_OF_BUFFER]; //缓冲区是个循环队列
bool g_continue = true; //控制程序结束
HANDLE g_hMutex; //用于线程间的互斥
HANDLE g_hFullItems; //缓冲区中被占用的项
HANDLE g_hEmptyItems; //缓冲区中的空项
DWORD WINAPI Producer(LPVOID); //生产者线程,dword 变量类型的内存占位
DWORD WINAPI Consumer(LPVOID); //消费者线程
int main()
{
//创建各个互斥信号
g_hMutex = CreateMutex(NULL,FALSE,NULL);
g_hFullItems = CreateSemaphore(NULL,0,SIZE_OF_BUFFER,NULL);//创建信号灯,createsemaphore常常被用作多线程同步
g_hEmptyItems = CreateSemaphore(NULL,SIZE_OF_BUFFER,
SIZE_OF_BUFFER,NULL);
//缓冲区初始化
for (int i = 0; i< SIZE_OF_BUFFER;++i){
g_buffer[i] = -1; //当值为-1时该项为空
}
const unsigned short PRODUCERS_COUNT =3; //生产者的个数
const unsigned short CONSUMERS_COUNT =2; //消费者的个数
//总的线程数
const unsigned short THREADS_COUNT = PRODUCERS_COUNT+CONSUMERS_COUNT;
HANDLE hThreads[THREADS_COUNT]; //各线程的handle
DWORD producerID[PRODUCERS_COUNT]; //生产者线程的标识符
DWORD consumerID[CONSUMERS_COUNT]; //消费者线程的标识符
//创建生产者线程
for ( i=0;i<PRODUCERS_COUNT;++i){
hThreads[i]
=CreateThread(NULL,0,Producer,NULL,0,producerID[i]);//CreateThread是window提供的API函数
if (hThreads[i]==NULL) return -1; //用此函数可创建一个线程
}
//创建消费者线程
for (i=0;i<CONSUMERS_COUNT;++i){
hThreads[PRODUCERS_COUNT+i]
=CreateThread(NULL,0,Consumer,NULL,0,consumerID[i]);
if (hThreads[i]==NULL) return -1;
}
while(g_continue){
if(getchar()){ //按回车后终止程序运行
g_continue = false;
}
}
return 0;
}
//生产一个产品。简单模拟了一下,仅输出新产品的ID号
void Produce()
{
cout <<endl<< "Producing " << ++ProductID << " ... ";
cout << "Succeed" << endl;
}
//把新生产的产品放入缓冲区
void Append()
{
cout << "Appending a product ... ";
g_buffer[in] = ProductID;
in = (in+1)%SIZE_OF_BUFFER;
cout << "Succeed" << endl;
//输出缓冲区当前的状态
for (int i=0;i<SIZE_OF_BUFFER;++i){
cout << i <<": ";
if (g_buffer[i]==-1)
cout << "null";
else
cout << g_buffer[i];
if (i==in) cout << '\t' << " <-- 生产";
if (i==out) cout << '\t' << " <-- 消费";
cout << endl;
}
}
//从缓冲区中取出一个产品
void Take()
{
cout << endl<<"Taking a product ... ";
ConsumeID = g_buffer[out];
g_buffer[out]= -1;
out = (out+1)%SIZE_OF_BUFFER;
cout << ConsumeID<<"--Succeed" << endl;
//输出缓冲区当前的状态
for (int i=0;i<SIZE_OF_BUFFER;++i){
cout << i <<": ";
if (g_buffer[i]==-1)
cout << "null";
else
cout << g_buffer[i];
if (i==in) cout << '\t' << " <-- 生产";
if (i==out) cout << '\t' << " <-- 消费";
cout <<endl;
}
}
//消耗一个产品
void Consume()
{
cout << "Consuming " << ConsumeID << " ... ";
cout << "Succeed" << endl;
}
//生产者
DWORD WINAPI Producer(LPVOID lpPara)
{
while(g_continue){
int i=rand()%5;
Sleep(i*1000);
WaitForSingleObject(g_hEmptyItems,INFINITE);//等待信号灯
WaitForSingleObject(g_hMutex,INFINITE);
Produce();
Append();
ReleaseMutex(g_hMutex);
ReleaseSemaphore(g_hFullItems,1,NULL);
}
return 0;
}
//消费者
DWORD WINAPI Consumer(LPVOID lpPara)
{
while(g_continue){
int i=rand()%5;
Sleep(i*1000);//该线程释放当前的控制权1500毫秒,让系统调度其他线程
WaitForSingleObject(g_hFullItems,INFINITE);
WaitForSingleObject(g_hMutex,INFINITE);
Take();
Consume();
ReleaseMutex(g_hMutex);
ReleaseSemaphore(g_hEmptyItems,1,NULL);
}
return 0;
}
关于操作系统生产者消费者问题和操作系统生产者消费者问题课程设计的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。
操作系统生产者消费者问题的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于操作系统生产者消费者问题课程设计、操作系统生产者消费者问题的信息别忘了在本站进行查找喔。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。