操作系统实验报告【太原理工大学】

操作系统实验报告

温馨提示:仅供参考!


一、进程调度程序设计


1.程序清单

#include<stdio.h>
#include<stdlib.h>
#define furthest 5
struct process       /*PCB STRUCTURE*/
{ 
	int id;
	int priority;
	int cputime;
	int alltime;
	char state;
	int next; 
}prochain[furthest+1]; //队列中有5项实际的内容,而数组0号内放着head,next指向下一个数组的0号 
	int procnum;
	int rand();
	int algo;
	int run,head,tail,j;
void init();//声明函数 
void prisch();//声明函数
void print(); //声明函数
void timesch();//声明函数
void insert(int q);//声明函数
void insert2(); //17-22行对函数进行了声明,如果使用自己定义的函数,这个函数在调用它的函数的后面(main函数后面),
				//必须在调用之前进行函数声明。因为程序是从上到下逐行编译的,若无函数声明,则会无法识别函数。
				//则函数头必须写在main函数的前面如果使用自己定义的函数,这个函数在调用它的函数的后面(main函数后面)。
int main(){		 
	agan: printf("type the algorithm is (1:RR,2:PRIO):");
	scanf("%d",&algo);
	if(algo==2){ 
		printf("output of priority.\n");  //优先级 
		init();
		prisch();
		}
	else{
		if(algo==1){
			printf("output of round robin.\n");  //轮转法 
			init();
			timesch();}
		else{
			printf("try again,please\n");
			goto agan;
			}
		}
	for(j=1;j<=40;j++)    
		{  printf("="); }
	printf("\n\n");
	for(j=1;j<=40;j++)
		{ printf("="); }
	printf("\n\n");
	printf("system finished\n"); 
}
void print(){                    
    int k,p;
	for(k=1;k<=40;k++)
		printf("=");
	printf("\nrunning proc.                ");
	printf("waiting queue.");
	printf("\n    %d      ",prochain[run].id);
	p=head;
	while(p!=0){ 
		printf("%5d",p);
		p=prochain[p].next;}
		printf("\n");
	for(k=1;k<=40;k++)
		printf("=");
	printf("\n");
	printf(" id            ");
	for(k=1;k<furthest+1;k++)
		printf("%5d",prochain[k].id);
	printf("\n");
	printf("priority       ");
	for(k=1;k<furthest+1;k++)
		printf("%5d",prochain[k].priority);
	printf("\n");
	printf("cputime        ");
	for(k=1;k<furthest+1;k++)
		printf("%5d",prochain[k].cputime);
	printf("\n");
	printf("alltime        ");
	for(k=1;k<furthest+1;k++)
		printf("%5d",prochain[k].alltime);
	printf("\n");
	printf("state          ");
	for(k=1;k<furthest+1;k++)
		printf("%5c",prochain[k].state);
	printf("\n");
	printf("next           ");
	for(k=1;k<furthest+1;k++)
		printf("%5d",prochain[k].next);
	printf("\n");
}

void insert(int q)      /*INSERT A PROCESS*/
{       
	int p,s;
	p=head;
	s=prochain[head].next;
	while((prochain[q].priority<prochain[s].priority)&&(s!=0)){ 
		p=s;
		s=prochain[s].next;
		}
		prochain[p].next=q;
		prochain[q].next=s;
} 
void insert2()    /*PUT A PROCESS ONTO THE TAIL OF THE QUEUE*/
{       
		prochain[tail].next=run;
		tail=run;
		prochain[run].next=0;
	}

void init()     /*CREATE A WAITING QUEUE*/
	{       
		int i;
		head=0;
		if(algo==2){ 
			for (i=1;i<furthest+1;i++){ 
				prochain[i].id=i;                      //进程标识符id 
				prochain[i].priority=(rand()+11)%41;   //优先数/轮转时间片数 
				prochain[i].cputime=0;                 //占用CPU时间片数
				prochain[i].alltime=(rand()+1)%7;      //进程所需时间片数
				prochain[i].state='W';                 //进程状态 
				prochain[i].next=0;                    //链指针 
				if((prochain[i].priority<prochain[head].priority)&&(head!=0))
					insert(prochain[i].id);
				else{
					prochain[i].next=head;
					head=prochain[i].id;
					}
			}     
		}
		else{
			for (i=1;i<furthest+1;i++){ 
				prochain[i].id=i;
				prochain[i].priority=(rand()+1)%3+1;
				prochain[i].cputime=0;
				prochain[i].alltime=(rand()+1)%7;
				prochain[i].state='W';
				prochain[i].next=(i+1)%(furthest+1);}
				head=1;
				tail=furthest; 
				prochain[furthest].next=0;
				}
			run=head;
			prochain[run].state='R';
			head=prochain[head].next;
			prochain[run].next=0;
			print();
		}
//prisch为优先级 
void prisch()      /*THE PROCESS WITH PRIO ALGORITHM*/
	{       
		while(run!=0){
		if(prochain[run].alltime==0){
				prochain[run].state='F';
				prochain[run].next=0;
				if(head!=0){
					run=head;
					prochain[run].state='R';
					head=prochain[head].next;}
				else{ 
					prochain[0].id=prochain[run].id;
					run=0;
					}
			}                 //运行中要先用if语句判断一下第一个运行的alltime是否为0,若为0, 
							 //则直接从RUN状态变为FINISH状态,接着才能运行下面的内容,否则
							 //alltime为负值则会一直无限循环下去 
			prochain[run].cputime+=1;
			prochain[run].priority-=3;
			prochain[run].alltime-=1;

			/*下面的运行后也要再用if语句判断一下运行后的alltime是否为0,
			若为0, 则直接从RUN状态变为FINISH状态,接着才能运行下面的内
			容,否则alltime为负值也会一直无限循环下去 */ 
			if(prochain[run].alltime==0){
				prochain[run].state='F';
				prochain[run].next=0;
				if(head!=0){
					run=head;
					prochain[run].state='R';
					head=prochain[head].next;}
				else{ 
					prochain[0].id=prochain[run].id;
					run=0;
					}
			}
			else{  
				if((prochain[run].priority<prochain[head].priority)&&(head!=0)){ 
					prochain[run].state='W';
					insert(run);
					run=head;
					prochain[run].state='R';
					head= prochain[head].next;
				}
			}
		print();
		}
 	}
/*
	下面轮转法中timesch函数下的重要性就相当于用priority表示,使用priority次数用尽
	后,继续执行下一个进程,在进程都结束后,占用cpu时间开始累加直至结束。 
*/ 
void timesch()      /*THE PROCESS WITH RR ALRORITHM*/
	{	  
		while(run!=0){ 
			
			if(prochain[run].alltime==0){ 
				prochain[run].state='F';
				prochain[run].next=0;
				if(head!=0){ 
					run=head;
					prochain[run].state='R';
					head=prochain[head].next;
					}
				else{ 
					prochain[0].id=prochain[run].id;
					run=0;
					}
			}
			//上述if语句同优先级方法类似,先判断alltime是否为0,可以解决死循环问题 
			
			prochain[run].alltime-=1;
			prochain[run].cputime+=1;
			if(prochain[run].alltime==0){ 
				prochain[run].state='F';
				prochain[run].next=0;
				if(head!=0){ 
					run=head;
					prochain[run].state='R';
					head=prochain[head].next;
					}
				else{ 
					prochain[0].id=prochain[run].id;
					run=0;
					}
			}
			else{ 
				if((prochain[run].cputime==prochain[run].priority)&&(head!=0)){ 
					prochain[run].state='W';
					prochain[run].cputime=0;
					insert2();
					run=head;
					prochain[run].state='R';
					head=prochain[head].next;
					}
				}
		print();
		}
}

2.运行结果


① 简单轮转法:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


② 优先数法

在这里插入图片描述

3.分析总结

此实验运用了俩种方法进行了程序的调度。在简单轮转方法中,本程序代码中timesch函数下的重要性用priority表示,使用priority次数用尽后,继续执行下一个进程,在进程都结束后,占用cpu时间才开始累加直至结束。
而在优先数方法中,每一次都要判断一下优先级最高的进程,然后alltime进行减1,cputime加1处理,直到alltime为0后,进程状态才由“R”变为“F”。
在本实验纠错过程中,两种方法下程序在第一次不判断alltime是否为0时就会出现所谓的“死”循环,在时间片减1、优先数减3或者时间片减1、cpu时间加1后,还要再次进行alltime是否为0的判断,两者都要存在才能保证程序的正常运行。


二、页式虚拟存储管理程序设计


1.程序清单

#include<stdio.h>
#define number 7
#define null -1
struct page_table
{
	int page_number;   
	int sign;  
	int block;  
	int modify;  
	int place;  
};
struct page_table work_page[number]={{0,1,5,0,11},{1,1,8,0,12},{2,1,9,0,13},
				{3,1,1,0,21},{4,0,null,0,22},{5,0,null,0,23},{6,0,null,0,121}};
struct performance_list
{
	int list_number;
	char operation[8];
	int page_number;
	int page_address;
};
struct performance_list work_list[12]={{1,"+",0,70},{2,"+",1,50},
			{3,"*",2,15},{4,"存",3,21},{5,"取",0,56},{6,"-",6,40},{7,"移位",4,53},
			{8,"+",5,23},{9,"存",1,37},{10,"取",2,78},{11,"+",4,1},{12,"存",6,84}};
int main(){	
	int new_number,new_sign,new_block,new_modify,new_list_number,j;
	char new_place[6],new_operation[8]; 
	int p[4]={0,1,2,3};//四块主存块 
	int k=0;
	int m=4;
	long new_address;
	printf("\n   序号\t  操作\t  页号\t  页内地址\t 标志位\t  绝对地址\t  页号变化\t 块号\t绝对地址\n");
	for(int i=0;i<12;i++)
	{
		new_list_number=work_list[i].list_number;
		printf("%5d",new_list_number);  //输出序号 
		new_number=work_list[i].page_number;
		new_sign=work_page[new_number].sign;
		new_block=work_page[i].block;
		new_modify=work_page[i].modify;
		if(new_sign==1)
			new_address=work_page[new_number].block*1024+work_list[i].page_address;
		else{			
			j=p[k];
			p[k]=new_number;
			k=(k+1)%m;
			work_page[new_number].sign=1;   //修改标志位改为1
			work_page[new_number].block=work_page[j].block;
			work_page[j].block=-1;
			work_page[j].sign=0;
			work_page[j].modify=0;
			new_address=work_page[new_number].block*1024+work_list[i].page_address;
		}
		if(work_list[i].operation=="存")
			work_page[new_number].modify=1;
		printf("	%5s",work_list[i].operation);//输出操作 
		printf("      %d",new_number);//输出页号 
		printf("	    %2d",work_list[i].page_address);//输出页内地址 
		printf("             %d",new_sign);//输出标志位 
		if(new_sign==1)
			printf("       %d",new_address);// 输出绝对地址 
		else
			printf("        *%d",work_list[i].page_number);//输出*页号 
		if(new_sign==1)
			printf("                       \t");//无地址转换输出空格 
		else
			printf("              %d->%d\t",work_list[i].page_number,j);//展示地址的变化 
		printf("  %d",work_page[new_number].block);//输出相应的块号 
		printf("       %d",new_address);
		printf("\n");
	}
}

2.运行结果

在这里插入图片描述

3.分析总结

首先将作业的页表与作业的指令序列链接起来,形成一个新表,然后根据新表通过判断是否为标志位以及是否为“存”指令进行绝对地址的计算。在页表中通过增加是否修改过的标志,(当执行“存”指令、“写”指令时把对应页的修改标志置成“1”,表示该页修改过,否则为“0”,表示该页未修改过),来对“存”指令以及页面是否调出进行了判断。实验中标志位为“0”时,进行了页号的修改,修改后进行绝对地址的计算。


三、几种操作系统界面的熟悉


1.程序清单

① C语言编写9*9乘法表

在这里插入图片描述


② python 编写9*9乘法表

在这里插入图片描述

2.运行结果

在这里插入图片描述


在这里插入图片描述

3.分析总结

熟悉多种操作系统的界面,在熟练使用机器的基础上,了解了各种操作命令和系统调用在系统中的大致工作过程。熟悉系统实用程序的调用方法和各种系统调用模块的功能和作用,从而有效地使用计算机。

  • 16
    点赞
  • 121
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

栈老师不回家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值