实验内容:
1.实验目的和要求
(1)理解生产者/消费者模型及其同步/互斥规则。
(2)了解Windows同步对象及其特性。
(3)熟悉实验环境,掌握相关API的使用方法。
(4)设计程序,实现生产者/消费者进程的同步与互斥。
2.实监内容
在Visual C++ 6.0集成开发环境下使用C语言,利用相应的Win32 API函数,以生产者/消费者模型为依据,创建一个控制台进程,在该进程中创建n个进程模拟生产者和消费者,实现进程的同步与互斥。
3.实验原理与提示
进程数据结构:每个进程有一个进程控制块(PCB)表示。进程控制块可以包含如下信息:进程类型标号,进程系统号,进程状态(本程序未用),进程产品(字符),进程链指针等。系统开辟了一个缓冲区,大小由buffersize指定。程序中有三个链队列,一个链表。一个就绪队列(ready),两个等待队列:生产者等待队列( producer);消费者等待队列(consumer)。一个链表(over),用于收集已经运行结束的进程。
本程序通过函数模拟信号量的原子操作。
算法的文字描述:
(1由用户指定要产生的进程及其类别,存入就绪队列。
(2)调度程序从就绪队列中提取一个就绪进程运行,如果申请的资源不存在则进入相应的等待队列,调度程序调度就绪队列中的下一个进程﹔进程运行结束时,会检查相应的等待队列,激活等待队列中的进程进入就绪队列;运行结束的进程进人over链表。重复这一过程直至就绪队列为空。
(3)程序询问是否要继续?如果要继续转至(1)开始执行,否则退出程序。
参考代码
#include <stdio.h>
#include <malloc.h>
#define buffersize 5 //假设有5个缓冲区
int processnum=0; //初始化产品数量
struct pcb /* 定义进程控制块PCB*/
{
int flag;
int numlabel;
char product;
char state;
struct pcb*processlink;
}*exe=NULL,*over=NULL;
typedef struct pcb PCB;
PCB* readyhead=NULL,* readytail=NULL;
PCB* consumerhead=NULL,* consumertail=NULL;
PCB* producerhead=NULL,* producertail=NULL;
int productnum=0; //产品数量
int full=0,empty=buffersize; //信号量
char buffer[buffersize]; //缓冲区
int bufferpoint=0; //缓冲区指针
void linklist(PCB * p,PCB* listhead) //创建就绪队列
{
PCB*cursor=listhead;
while(cursor->processlink!=NULL){
cursor=cursor->processlink;
}
cursor->processlink=p;
}
void freelink(PCB* linkhead)
{
PCB* p;
while(linkhead!=NULL)
{
p=linkhead;
linkhead=linkhead->processlink;
free(p);
}
}
void linkqueue(PCB* process,PCB** tail) //初始化队列
{
if((*tail)!=NULL)
{
(*tail)->processlink=process;
(*tail)=process;
}
else{
printf("队列未初始化!");}
}
PCB* getq(PCB*head,PCB** tail)
{
PCB* p;
p=head->processlink;
if(p