系列文章目录
文章目录
- 系列文章目录
- ***实验内容***
- 背景知识
-
- 二、源代码
-
实验内容
1.问题描述:一组生产者向一组消费者提供消息,它们共享一个有界缓冲池,生产者向其中投放消息,消费者从中取得消息。假定这些生产者和消费者互相等效,只要缓冲池未满,生产者可将消息送入缓冲池,只要缓冲池未空,消费者可从缓冲池取走一个消息。
2.功能要求:根据进程同步机制,编写一个解决上述问题的程序,可显示缓冲池状态、放数据、取数据等过程。
背景知识
1.了解经典同步问题“生产者和消费者
生产者与消费者可以通过一个环形缓冲池联系起来,环形缓冲池由几个大小相等的缓冲块组成,每个缓冲块容纳一个产品.每个生产者可不断地每次往缓冲池中送一个生产产品,而每个消费者则可每次从缓冲池中取出一个产品.
分析和理解
(1)既存在合作同步问题,也存在临界区互斥问题
合作同步:当缓冲池全满时,表示供过于求,生产者必须等待,同时唤醒消费者;当缓冲池全空时,表示供不应求,消费者应等待,同时唤醒生产者。互斥:缓冲池显然是临界资源,所在生产者与消费都要使用它,而且都要改变它的状态.
(2)基于环形缓冲区的生产者与消费者关系形式描述:公用信号量mutex:初值为1,用于实现临界区互斥生产者私用信号量empty
思路
用C++设计一个生产者和消费者在同一个进程地址空间内执行的两个进程,生产者生产物品,消费者消费物品,然后将物品放置在一个空缓冲区中供消费者消费。消费者从缓冲区中获得物品,然后释放缓冲区。
同时设置一个互斥信号量,用以阻止生产者线程和消费者进程同时操作缓冲区;还设置了一个信号量,当生产者生产出一个物品时可以用它向消费者发出信号;
另一个信号量,消费者释放出一个空缓冲区时可以用它向生产者发出信号;
并且分别独立设置了将数据放人缓冲区和从缓冲区取出数据的操作,让生产者消费者两个函数设计起来更简洁
这里要注意的是:缓冲区满时不能生产,缓冲区空时不能消费
————————————————
二、源代码
代码如下(示例):
#include <stdio.h>
#include <windows.h>
#include<iostream>
using namespace std;
#define N 5
typedef int semaphore;
semaphore mutex=1;
semaphore empty=N;
semaphore full=0;
semaphore buff[N];
semaphore in=0, out=0;
void p(semaphore *x)
{ *x=(*x)-1;}
void v(semaphore *y)
{ *y=(*y)+1;}
void produce_item(int *item)
{
cin>>*item;
}
void enter_item(int x)
{
buff[in]=x;
cout<<"输入了"<<buff[in]<<"到缓冲区 buff["<<in<<"]"<<endl;
in=(in+1)%N;
}
void remove_item(int *yy)
{
cout<<"从缓冲区buff["<<out<<"]"<<"取走"<< buff[out]<<endl;
*yy=buff[out];
buff[out]='k';
cout<<"因此缓冲区buff["<<out<<"]"<<"已经变成空"<<endl;
out=(out+1)%N;
}
void consume_item(int y)
{
cout<<"消费从缓冲区取出的产品"<<y<<endl;
}
void producer();
void consumer();
void producer()
{
int item;
{
Sleep(1000);
produce_item(&item);
p(&empty);
p(&mutex);
enter_item(item);
v(&mutex);
v(&full);
if(full==N)
{
cout<<"缓冲区已满,无法在生产物品,请先消费"<<endl;
consumer();
}
}
}
void consumer()
{
int get_item;
Sleep(1000);
p(&full);
p(&mutex);
remove_item(&get_item);
v(&mutex);
v(&empty);
consume_item(get_item);
}
int main()
{
cout<<"*********************************"<<endl;
cout<<"*欢迎使用生产者消费者系统系统*"<<endl;
while(1) {
cout<<"*请输入"<<endl;
cout << "1.生产者"<<endl;
cout << "2.消费者"<<endl;
int i=0;
cin>>i;
if(i==1)
producer();
else{
if(empty==N)
cout<<"缓冲区已空,无法在消费物品,请先生产"<<endl;
else
consumer();
}
}
return 0;
}
运行结果
结论
简单实现了生产者消费者算法,实现了可显示缓冲池状态、放数据、取数据等过程。还是过于抽象了,如果能用进度条那种形式就更好了,但是能力暂时有限,只是实现了其中的算法思想,还需要继续改进学习。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)