⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 操作系统实验一源程序.txt

📁 这是一个模拟操作系统中多进程并发调度的问题。
💻 TXT
字号:
#include <stdio.h>
#include <string.h>
#include <math.h>
struct pcbtype{
	int id,priority,wait;
	char status[8];
};   /*定义进程控制块*/
struct semtype{
	int value;  /*表示该类资源的可用资源*/
	int waitptr;  //表示该资源等待队列中的第一个进程
};    /*表示每一类资源*/
struct pcbtype pcb[4];
struct semtype sem[4];
FILE *fp;
int i,rp,m1,m2;  /*用rp表示CPU的使用状态,0表示空闲,非0则表示有进程正在使用CPU*/
char stack[4][6];
char addr;
char kou=' ';
char pr[]="process";
char re[]="ready\0";
char ru[]="running";
char bl[]="blocked";
char hc='\n';
void init()    //初始化
{
	int j,k;
	for (j=1;j<=3;j++)   
	{
		pcb[j].id=j;
		pcb[j].priority=j;
		pcb[j].wait=0;
		pcb[j].status[0]=' ';  //初始状态,各进程均为就绪状态
		pcb[j].status[1]='r';
		pcb[j].status[2]='e';
		pcb[j].status[3]='a';
		pcb[j].status[4]='d';
		pcb[j].status[5]='y';
		pcb[j].status[6]=' ';
		pcb[j].status[7]='\0';
		sem[j].value=0;
		sem[j].waitptr=0;
		for(k=1;k<=5;k++)
			stack[j][k]='\0';
	}
	sem[3].value=4;
	i=0;
	addr='0';m1=0;m2=0;
	rp=0;
}
int find() /*从就绪队列ready中查找优先级最高的进程,返回该进程名*/
{  
	int j;
	int find1;
	j=1;
	while(strcmp(pcb[j].status," ready ")&&j<=3)
		j=j+1;
	if(j<=3)
		find1=j;
	else
		find1=0;
	return(find1);
}
void p(int se,int pd,char ad) /*进程pd申请占用资源se,没有可用资源则阻塞进程*/
{
	int w;
	sem[se].value=sem[se].value-1;
	if(sem[se].value<0) /*没有可用资源,则进程pd阻塞*/
	{
		printf("process %d blocked\n",pd);
		fprintf(fp,"%s%c%d%c%s%c",pr,kou,pd,kou,bl,hc);
		rp=0;   /*进程pd被阻塞,释放CPU,则CPU空闲*/

		pcb[pd].status[0]=' '; //将进程w的状态置为blocked
		pcb[pd].status[1]='b';
		pcb[pd].status[2]='l';
		pcb[pd].status[3]='o';
		pcb[pd].status[4]='c';
		pcb[pd].status[5]='k';
		pcb[pd].status[6]='e';
		pcb[pd].status[7]='d';
		w=sem[se].waitptr; /*进程w是资源se等待队列的对头*/
		if(w==0)  /*等待队列为空*/
		sem[se].waitptr=pd;  /*置资源se等待队列的对头为进程pd*/
		else  /*等待队列不为空*/
			while (pcb[w].wait!=0)/*循环找到等待队列的队尾,将进程pd插入队尾*/
			{
				w=pcb[w].wait;////有错////
				pcb[w].wait=pd;
			}
		stack[pd][1]=(char)i;   //保存进程pd在阻塞时的运行结果
		stack[pd][2]=ad;   //保存进程pd的阻塞断点
	}
}
void v(int se,int pd,char ad) /*释放资源,则将等待队列的首进程唤醒并置入就绪队列*/
{ 
	int w;char wa[]="wackup";
	sem[se].value=sem[se].value+1;
	if(sem[se].value<=0)
	{ 
		w=sem[se].waitptr;  //进程w为等待队列的对头进程
		sem[se].waitptr=pcb[w].wait;  //将进程w从等待队列中删除,对头指针waitptr后移一位,指向下一个进程
		pcb[w].status[0]=' '; //将进程w的状态置为ready,放入ready就绪队列
		pcb[w].status[1]='r';
		pcb[w].status[2]='e';
		pcb[w].status[3]='a';
		pcb[w].status[4]='d';
		pcb[w].status[5]='y';
		pcb[w].status[6]=' ';
		pcb[w].status[7]='\0';
		printf("backup process%d\n",w);
		fprintf(fp,"%s%c%s%d%c",wa,kou,pr,w,hc);
		stack[pd][1]=(char)i;   //保存运行结果及断点位置
		stack[pd][2]=ad;  //由于有新的进程被唤醒,pd进程可能会被阻塞
	}
}
void process1()  //申请资源sem1
{ 
	char pr1[]="process1";
	char pri[]="printing…ml=";
	char ca[]="calls p on seml";
	if(addr=='m')  
           goto m;
	i=1;
a:  printf("process1 calls p on sem1\n");
    fprintf(fp,"%s%c%s%c",pr1,kou,ca,hc);
    p(1,1,'m');
    if(sem[1].value<0)  //没有可用资源,返回
       goto e;
m:  printf("process1 printing…m1=%d\n",m1);
    fprintf(fp,"%s%c%s%d%c",pr1,kou,pri,m1,hc);
    printf("process1 i=%d\n",i);
    fprintf(fp,"%s%c%d%c",pr1,kou,i,hc);
    i=i+5;    //执行运算
    goto a;
e:  return;	
}
void process2()  //申请资源sem2,释放资源sem1
{ 
	char pr2[]="process2";
	char cal[]="calls p on sem2";
	char ca2[]="calls v on sem1 m1=";
	char I[]="I=";
	if(addr=='m')  
		goto m;		
	if(addr=='n') 
		goto n;
	i=1;
a: 	printf("process2 calls p on sem2\n");
   	fprintf(fp,"%s%c%s%c",pr2,kou,cal,hc);
	p(2,2,'m');   //申请资源sem2
	if(sem[2].value<0)  //没有可用资源,返回
		goto e;
m:	m1=2*m2;
	printf("process2 calls v on sem1 m1=%2d\n",m1);
	fprintf(fp,"%s%c%s%2d%c",pr2,kou,ca2,m1,hc);
	v(1,2,'n');   //释放资源sem1
	if(sem[1].value>=0)
		goto e;
n:	printf("  process2 i=%2d\n",i);
	fprintf(fp,"%s%c%s%d%c",pr2,kou,I,i,hc);
	i=i+10;
	goto a;
e:	return;
}
void process3()   //申请资源sem3,释放资源sem2
{
	char pr3[]="process3 calls p on";
	char s3[]="sem3";
	char s2[]="sem2 m2=";
	if(addr=='m')
		goto m;
	if(addr=='n')
		goto n;
	i=1;
a:	printf("process3 calls p on sem3\n");
	fprintf(fp,"%s%s%c",pr3,s3,hc);
	p(3,3,'m');     //申请资源sem3
	if(sem[3].value<0)
		goto n;
	m2=i;
	printf("process3 calls p on sem2 m2=%2d\n",m2);
	fprintf(fp,"%s%s%2d%c",pr3,s2,m2,hc);
	v(2,3,'m');    //释放资源sem2
	if(sem[2].value<=0)
		goto n;		
m:	i=i+1;
	goto a;
n:	return;
}
void scheduler()  //系统调度程序
{	
	int rdy;
	rdy=find();   //查找就绪队列中优先级最高的进程rdy
	while(rdy!=0)
	{
		if(rp==0)  //rp为0,表示CPU空闲,可执行rdy进程
		{
			rp=rdy;
			pcb[rdy].status[0]=' ';			
			pcb[rdy].status[1]='r';
			pcb[rdy].status[2]='u';	
			pcb[rdy].status[3]='n';	
			pcb[rdy].status[4]='n';	
			pcb[rdy].status[5]='i';	
			pcb[rdy].status[6]='n';	
			pcb[rdy].status[7]='g';	
		}
		else    //rp不为0 则rp进程占用CPU
			if(pcb[rdy].priority<pcb[rp].priority) //比较优先级,若rdy进程优先级高于当前运行的rp进程,则执行rdy进程,而将rp进程置入就绪队列
			{	                                
				pcb[rp].status[0]=' ';
				pcb[rp].status[1]='r';
				pcb[rp].status[2]='e';
				pcb[rp].status[3]='a';
				pcb[rp].status[4]='d';
				pcb[rp].status[5]='y';
				pcb[rp].status[6]=' ';
				pcb[rp].status[7]='\0';
				printf("process%d ready\n",rp);
				fprintf(fp,"%s%c%d%c%s%c",pr,kou,rp,kou,re,hc);
				pcb[rdy].status[0]=' ';
				pcb[rdy].status[1]='r';
				pcb[rdy].status[2]='u';
				pcb[rdy].status[3]='n';
				pcb[rdy].status[4]='n';
				pcb[rdy].status[5]='i';
				pcb[rdy].status[6]='n';
				pcb[rdy].status[7]='g';
				rp=rdy;   //设置rdy作为当前运行的进程
			}	
		printf("process%d running\n",rp);
		fprintf(fp,"%s%c%d%c%s%c",pr,kou,rp,kou,ru,hc);
		i=(int)stack[rp][1]; 
		addr=stack[rp][2];    //获取断点现场信息即运行结果和断点状态 
		switch(rp)
		{
			case 1:process1();
				break;
			case 2:process2();
				break;
			case 3:process3();
				break;
			default: printf("rp error");	
		}									
			rdy=find();
	}
}
main()
{
	char le[]="Let us begin manage of process\n";
	if((fp=fopen("jc.c","w"))==NULL)
	     printf("Can't open this file");
	printf("Let us begin manage of process\n");
	fprintf(fp,"%s",le);
	init();    //初始化
	scheduler();  //系统运行调度程序
	fclose(fp);
}					

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -