操作系统的进程同步算法——记录型信号量模拟

记录型信号量进程同步机制拥有记录型的数据结构,其中包括某种临界资源的可供访问的数量和进程阻塞队列,进程在操作时只能采用wait()和signal(),两种原子操作。其算法模拟如下:

#include <stdio.h>
#include <string>
#include <stdlib.h>
#include <iostream>
using namespace std;
//信号量机制的同步和互斥//
//进程数据结构

//链式队列的数据结构
typedef struct process{
	int num;//进程编号
	struct process *next;//下指针
}*processptr;

typedef struct Link {
	process *front, *rear;//队列的头尾指针
}*LinkQNode;

void InitQNode(LinkQNode q) {
	//初始化队列
	q->front = q->rear = (processptr)malloc(sizeof(process));
	q->front->next = NULL;
}

void Insert(LinkQNode q,int num) {
	processptr p1 = (process *)malloc(sizeof(process));
	p1->num = num;
	p1->next = NULL;
	q->rear->next = p1;
	q->rear = p1;
}

int Select(LinkQNode q) {
	//出队操作
	if (q->rear == q->front) {
		//cout << "进程队列为空" << endl;
		return 0;
	}
	processptr p = (process *)malloc(sizeof(processptr));
	p = q->front->next;
	q->front->next = q->front->next->next;
	int num ;
	num = p->num;
	if (q->rear == p)
		q->rear = q->front;//如果只有一个元素,那么队头指针等于队尾指针
	free(p);
	return num;
}
//进程记录的数据结构
typedef struct semaphore{
	int value;//信号量的值,表征临界资源的请求和等待的进程数量
	LinkQNode L;//等待进程队列
}*semaphoreptr;


//信号量机制的操作
class Singal_opt {
	int num;//进程编号
public:
	Singal_opt(int n):num(n) {};
	~Singal_opt() {};
	void setnumber(int n);//设置进程编号
	void block(semaphoreptr s);//将等待进程插入到阻塞队列
	void wakeup(semaphoreptr s);//唤醒进程
	void wait(semaphoreptr s);//进程申请临界资源
	void singal(semaphoreptr s);//进程使用完毕并释放临界资源
};
void Singal_opt::setnumber(int n) {
	num = n;
}
void Singal_opt::block(semaphoreptr s) {
	//将进程状态转变为阻塞,即将当前进程入队
	Insert(s->L, num);
	cout << num << "号进程申请临界资源并且进入阻塞队列" << endl;
}
void Singal_opt::wakeup(semaphoreptr s) {
	//唤醒进程,即执行出队操作
	s->value++;
	int n;
	n = Select(s->L);
	if (n == 0) {
		//表示队以空
		cout << "阻塞队列已空" << endl;
	}
	else {
		cout << n << "号进程被唤醒,开始使用临界资源" << endl;
	}
}
void Singal_opt::wait(semaphoreptr s) {
	s->value--;//表示有一个进程申请临界资源
	if (s->value < 0) {
		//表示临界资源被占用
		//执行阻塞操作
		block(s);
	}
	else if (s->value >= 0) {
		cout << num << "号进程正在使用临界资源" << endl;
	}
}
void Singal_opt::singal(semaphoreptr s) {
	s->value++;//表示一个进程使用完毕并释放临界资源
	cout << num << "号进程使用完毕临界资源" << endl;
	while(s->value <= 0) {
		//表示还有进程在使用临界资源
		//从阻塞队列中唤醒一个临界资源
		wakeup(s);
	}
}
int main()
{
	Singal_opt p1(1), p2(2),p3(3);
	semaphoreptr s;
	s = (semaphore *)malloc(sizeof(semaphore));
	s->value = 1;
	s->L = (LinkQNode)malloc(sizeof(Link));
	InitQNode(s->L);
	p1.wait(s);
	p2.wait(s);
	p3.wait(s);
	processptr p = s->L->front->next;
	p1.singal(s);
    return 0;
}



PS:这段代码中我把signal写成singal了,-_-||

调试结果:


参考书籍:王道《2018年操作系统考研复习指导》

模拟进程管理 #include #include //Can only be used in independent situation; //#define getmem(type) (type*)malloc(sizeof(type)) #define buffersize 5 int processnum=0;//the num of processes struct pcb { /* 定义进程控制块PCB */ int flag;//flag=1 denote producer;flag=2 denote consumer; 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;// semaphore char buffer[buffersize];//缓冲区 int bufferpoint=0;//缓冲区指针 void linkqueue(PCB* process,PCB** tail); PCB* getq(PCB* head,PCB** tail); bool hasElement(PCB* pro); void display(PCB* p); void linklist(PCB* p,PCB* listhead); void freelink(PCB* linkhead); bool processproc(); bool waitempty(); bool waitfull(); void signalempty(); void signalfull(); void producerrun(); void comsuerrun(); bool hasElement(PCB* pro); 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!=NULL){ head->processlink=p->processlink; p->processlink=NULL; if( head->processlink ==NULL ) (*tail)=head; } else return NULL; return p; } bool processproc() { int i,f,num; char ch; PCB* p=NULL; PCB** p1=NULL; printf("\n 请输入希望产生的进程个数?"); scanf("%d",&num); getchar(); // if(num>=100){ // printf("您怎么要产生这么多进程!Demands Denied!"); // return false; // } for(i=0;iflag=f; processnum++; p->numlabel=processnum; p->state='w'; p->processlink=NULL; if(p->flag==1){ printf("您要产生的进程是生产者,它是第%d个进程。请您输入您要该进程产生的字符!\n",processnum); scanf("%c",&ch); getchar(); p->product=ch; productnum++; printf("您要该进程产生的字符是%c \n",p->product); } else { printf("您要产生的进程是消费者,它是第%d个进程。\n",p->numlabel); } linkqueue(p,&readytail); } return true; } bool waitempty() { if(emptynumlabel); linkqueue(exe,&producertail); return false; } else{ empty--; return true; } } void signalempty() { PCB* p; if(hasElement(producerhead)){ p=getq(producerhead,&producertail); linkqueue(p,&readytail); printf("等待中的生产者进程进入就绪队列,它的进程号是%d\n",p->numlabel); } empty++; } bool waitfull() { if(fullnumlabel); linkqueue(exe,&consumertail); return false; } else{ full--; return true;} } void signalfull() { PCB* p; if(hasElement(consumerhead)){ p=getq(consumerhead,&consumertail); linkqueue(p,&readytail); printf("等待中的消费者进程进入就绪队列,它的进程号是%d\n",p->numlabel); } full++; } void producerrun() { if(!waitempty()) return; printf("进程%d开始向缓冲区存数%c\n",exe->numlabel,exe->product); buffer[bufferpoint]=exe->product; bufferpoint++; printf("进程%d向缓冲区存数操作结束\n",exe->numlabel); signalfull(); linklist(exe,over); } void comsuerrun() { if(!waitfull()) return; printf("进程%d开始向缓冲区取数\n",exe->numlabel); exe->product=buffer[bufferpoint-1]; bufferpoint--; printf("进程%d向缓冲区取数操作结束,取数是%c\n",exe->numlabel,exe->product); signalempty(); linklist(exe,over); } void display(PCB* p) { p=p->processlink; while(p!=NULL){ printf("进程%d,它是一个",p->numlabel); p->flag==1? printf("生产者\n"):printf("消费者\n"); p=p->processlink; } } bool hasElement(PCB* pro) { if(pro->processlink==NULL) return false; else return true; } void main() { char terminate; bool element; printf("你想开始程序吗?(y/n)"); scanf("%c",&terminate); getchar(); //Queue initialize; readyhead=(PCB*)malloc(sizeof(PCB)); if(readyhead==NULL) return; readytail=readyhead; readyhead->flag=3; readyhead->numlabel=processnum; readyhead->state='w'; readyhead->processlink=NULL; consumerhead=(PCB*)malloc(sizeof(PCB)); if(consumerhead==NULL) return; consumertail=consumerhead; consumerhead->processlink=NULL; consumerhead->flag=4; consumerhead->numlabel=processnum; consumerhead->state='w'; consumerhead->processlink=NULL; producerhead=(PCB*)malloc(sizeof(PCB)); if(producerhead==NULL) return; producertail=producerhead; producerhead->processlink=NULL; producerhead->flag=5; producerhead->numlabel=processnum; producerhead->state='w'; producerhead->processlink=NULL; over=(PCB*)malloc(sizeof(PCB)); if(over==NULL) return; over->processlink=NULL; while(terminate=='y') { if(!processproc()) break; element=hasElement(readyhead); while(element){ exe=getq(readyhead,&readytail); printf("进程%d申请运行,它是一个",exe->numlabel); exe->flag==1? printf("生产者\n"):printf("消费者\n"); if(exe->flag==1) producerrun(); else comsuerrun(); element=hasElement(readyhead); } printf("就绪队列没有进程\n"); if(hasElement(consumerhead)) { printf("消费者等待队列中有进程:\n"); display(consumerhead); } else { printf("消费者等待队列中没有进程\n"); } if(hasElement(producerhead)) { printf("生产者等待队列中有进程:\n"); display(producerhead); } else { printf("生产者等待队列中没有进程\n"); } printf("你想继续吗?(press 'y' for on)"); scanf("%c",&terminate); getchar(); } printf("\n\n 进程模拟完成.\n"); //Free the room; freelink(over); over=NULL; freelink(readyhead); readyhead=NULL; readytail=NULL; freelink(consumerhead); consumerhead=NULL; consumertail=NULL; freelink(producerhead); producerhead=NULL; producertail=NULL; getchar(); }
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值