Hello!友友们好,我是薛定谔怀里的猫,操作系统是我在大三上学期学习的专业课,利用假期时间我把我的实验报告整理了出来,作为自己的学习记录和复习资料。这是实验报告一,其余的可以点开我头像看嗷!完整的代码放在了资源下载处,有需要的友友们可以自行下载嗷~~另外我还会整理C语言、数据结构、数据库原理、编译原理、数字逻辑等的实验报告,还有本人的一些期末大作业~欢迎可爱的你来光临我的小天地!
实验题目
模拟进程创建、终止、阻塞、唤醒原语
实验目的
通过设计并调试创建、终止、阻塞、唤醒原语功能,有助于对操作系统中进程控制功能的理解,掌握操作系统模块的设计方法和工作原理。
实验环境
1、硬件:pc 机及其兼容机。
2、软件:Windows OS,Dev-C++(C语言)。
实验内容
1、设计创建、终止、阻塞、唤醒原语功能函数。
2、设计主函数,采用菜单结构(参见后面给出的流程图)。
3、设计“显示队列”函数,目的能将就绪、阻塞队列中的进程信息显示在屏幕上,以供随时查看各队列中进程的变化情况。
算法设计
算法1:void main()//主函数,显示菜单,调用函数
输入:无
输出:无
1、创建就绪、运行、阻塞三个队列链表的头结点
2、打印菜单,接收用户的输入选项
3、while(flag==1) do
4、 switch:
5、 case 1~6:根据用户的输入调用相关函数;
6、 case 0:flag<-0;
7、 default: 提示用户输入无效;
8、end while
算法2:findList(PCB L,char name[])//查找输入的进程名在某队列中是否存在
输入:ready\run\block中某个队列;进程名
输出:1/0,1代表在队列中,0代表不在
1、p<-L->next;
2、for(;p!=NULL;p<-p->next) do
3、 if(strcmp(p->pname,name)==0) then //发现输入name与该
4、 return 1; 队列中某进程名相同
5、 end if
6、end for
7、return 0;
算法3:fcreate(PCB ready,PCB run,PCB block)//创建进程
输入:ready、run、block三个队列
输出:无
1、number++; //记录进程数量
2、if(number>10) then
3、 提示进程数超过10,不允许再创建
4、else
5、 while(flag==1) do
6、 输入新的进程名;
7、 while(op==1) do
8、 if(该进程名已经存在) then
9、 提示用户重新输入;
10、 else
11、 op<-0;
12、 end if
13、 end while
14、 尾插法创建一个新的进程放入就绪队列末尾;
15、 if(run->next==NULL) then
16、 frun(ready,run,block); //运行队列为空,调入刚创建的进程
17、 end if
18、 输入是否需要再创建一个新进程,是:flag<-1;否:flag<-0;
19、 end while
20、end if
算法4:frun(PCB ready,PCB run,PCB block)//运行进程,将当前运行进
输入:ready、run、block三个队列 程阻塞,调入新的运行进
输出:无 程
1、if(ready->next) then
2、 if(run->next!=NULL) then //当运行队列为空时
3、 将正在运行的进程阻塞
4、 end if
5、 将就绪队列队首进程调入运行队列
6、else
7、 提示用户就绪队列为空,无法调度
8、end if
算法5:fblock(PCB ready,PCB run,PCB block)//阻塞进程
输入:ready、run、block三个队列
输出:无
1、输入要阻塞的进程名;
2、if(在运行队列中查找到该进程) then
3、 在运行队列中取出该进程,修改状态;
4、 将该进程插入阻塞队列末尾;
5、else if(在就绪队列中查找到该进程)then
6、 提示要找的进程在就绪队列中,无法阻塞;
7、else if(在阻塞队列中查找到该进程)then
8、 提示要找的进程在阻塞队列中,无法阻塞;
9、else
10、 提示要查找的进程不在内存中,无法阻塞;
11、end if
算法6:fwakeup(PCB ready,PCB run, PCB block)//唤醒进程
输入:ready、run、block三个队列
输出:无
1、while(flag==1) do
2、 输入要唤醒的进程名;
3、 if(在阻塞队列中找到了该进程) then
4、 将该进程从block队列取出,修改状态;
5、 将该进程插入就绪队列末尾;
6、 end if
7、 if(此时运行队列中没有进程在运行) then
8、 frun(ready,run,block); //调入刚唤醒的进程运行
9、 end if
10、 提示进程已成功唤醒;
11、 输入是否需要再唤醒一个新进程,是:flag<-1;否:flag<-0;
12、end while
算法7:fdelete(PCB ready,PCB run, PCB block)//撤销进程
输入:ready、run、block三个队列
输出:无
1、while(flag==1) do
2、 re<-1;ru<-1;bl<-1;
3、 输入要撤销的进程名;
4、 if(在就绪队列中找到了该进程) then
5、 re<-0;
6、 将该进程从就绪队列删除;
7、 释放节点空间;
8、 end if
9、 if(在运行队列中找到了该进程) then
10、 ru<-0;
11、 将该进程从运行队列删除;
12、 释放节点空间;
13、 frun(ready,run,block); //将就绪队列首进程运行
14、 end if
15、 if(在阻塞队列中找到了该进程) then
16、 bl<-0;
17、 将该进程从阻塞队列删除;
18、 释放节点空间;
19、 end if
20、 if(re&&ru&&bl) then //要找的进程在三个队列中都不存在
21、 提示用户内存中没有该进程;
13、 输入是否需要再唤醒一个新进程,是:flag<-1;否:flag<-0;
14、end while
算法8:fshow(PCB ready,PCB run,PCB block)//输出所有进程信息
输入:ready、run、block三个队列
输出:无
1、showlist("就绪队列:",ready); //输出就绪队列中的所有进程信息
2、showlist("运行队列:",run); //输出就绪队列中的所有进程信息
3、showlist("阻塞队列:",block); //输出就绪队列中的所有进程信息
算法9:showlist(char str[], PCB p)//输出某个队列中的
输入:队列名称;ready\run\block三个队列中的某一个
输出:无
1、q<-p->next;
2、输出队列名;
3、if(q=NULL) then //队列为空
4、 输出“为空!”;
5、else
6、 while(q!=NULL) do //还没有将队列中所有节点进程信息输出
7、 输出当前节点的进程信息;
8、 q<-q->next;
9、 end while
10、end if
完整代码
详见资源下载处。
运行结果
1、创建p1、p2、p3、p4四个进程,因为刚开始运行队列为空,因此在创建完第一个进程后,系统就自动将其调入运行队列。
2、运行进程,其实也就是调度进程,选择该按钮后,系统会将正在运行的进程送到阻塞队列末尾,重新调入就绪队列首进程运行。
3、唤醒进程,用户输入想要唤醒的进程名后,检查该进程是否在阻塞队列中,若不在则给出提示,若在则将其唤醒并送入就绪队列末尾。
4、阻塞进程,用户输入进程名后,系统检查其在哪个队列中,或者是否在内存中,只要不在运行队列中就给出提示,若在就阻塞正在运行的进程,并将就绪队列首进程送入运行队列。
5、撤销进程,用户输入想要撤销的进程名,系统检查其是否在内存中,若不在则给出相应提示,若在则将其撤销。若撤销的是正在运行的进程,则系统重新调入新的进程运行。
实验总结
问题1:知识点遗忘
数据结构中单链表的相关操作(结构体的定义、链表的创建、尾插法插入节点、节点删除、元素查找、链表遍历等);一些常用的字符串处理函数,比如这次试验中所用到的:在查找函数中,需要在三个队列中看输入的进程名是否存在,就需要用到字符串对比函数strcmp;还有给字符串赋值的函数strcpy。
*解决方法:*我找出了大二上学期的链表实验代码,复习了一遍;然后各种函数的运用是遇到不会时就查CSDN。
问题2:逻辑问题
我是先把老师给的ppt代码框架粘贴过来,然后根据里面的思路编写代码,所有函数编写完后运行没报错。但是接下来仔细去检查功能时,就发现了虽然没报错,但是几乎每个函数的结果都和预想的不一致,
*解决方法:*通过使用调试的方法,反复检查,发现有很多逻辑歧义、错误,只能一点点改,而且每次改完都需要重新输入进程检查,比较花时间,这次实验代码写了4.5小时,有2.5个小时都在改这些问题。
问题3:界面美观问题
由于需要有很多的提示信息,而且控制台的输出信息很多,需要注意\n、\t的合理使用,来使界面整洁美观,这个在解决问题3的过程中伴随着同时更改就好。
问题4:最后的完善
① 发现有些实验指导书的要求ppt上没有。比如要求三个队列中进程总数不能超过10个,可以通过设置全局变量来实现。
② 还有我觉得ppt代码框架里一个不太准确的地方是:
创建进程时,这里应该用while循环检查,直到确定队列里没有与输入名字重名的,因为第二次输入还可能重名。另外判断重名可以单独写一个函数findList(PCB L,char name[]),找到返回1,没找到返回0。
③ 对进程运行函数frun功能加以扩展,当连续多次调用frun时,每一次调用都先将原运行进程送入阻塞队列末尾,然后用就绪队列之首进程替换掉原运行进程,实现进程切换。