}
图3.2
3.3.2定义结构体
我们知道,进程的一些基本信息都是放在PCB中的,及进程控制块,又因为它是进程存在的唯一标识,所以,PCB中的信息尤其重要。
首选我就定义了一个PCB的结构体用来存放进程的信息,如进程名name,进程号pid,进程优先级ppno,进程运行时间pruntime,进程等待时间waittime,进程时间片pts,运行状态state,带权周转时间w,进程等待时间片次数waittimes,中断状态BREAK等信息。
定义的这些变量之后,我们就可以很灵活的控制PCB中我们所要的信息了。
接下来,我又定义了一个就绪结构体,用来存放就绪进程的信息,优先级和进程名称,一个阻塞结构体,用来存放阻塞进程的信息,优先级和名称,一个名称结构体,用来临时存放进程的信息。
核心代码如下:
图3.3
3.4主函数功能的实现
3.4.1显示当前进程
这个功能主要就是显示自定义的进程和后来新创建的进程信息,以便于用户根据进程的信息进行其它的相关操作。
3.4.2创建进程
在程序运行之前,程序当中是没有进程的,所以一开始就要创建进程。
我首先定义了可以创建20个进程的数组stringstr[20],用来存放进程的名字。
当然,也可以定义更多的进程。
这创建的时后,为了避免用户每创建一个进程就要输入进程的一些信息,我采用的是随机获取的方式来给进程控制块分配信息,如进程号,进程运行时间,运行状态,优先级等。
首先我要说明的是这个程序的设计是根据单道程序设计来设计的,也就是每次只能有一个进程处于运行状态,所以,我采用了一个while语句来实现这个功能,当创建的进程中出现一个处于运行状态时,随后创建的进程当中就只能是处于就绪或阻塞状态了。
然后,每创建一个进程,我就根据进程的运行状态分别存放在就绪数组和阻塞数组中。
便于以后的调度和操作。
核心代码如下:
图3.4
运行结果:
图3.5
3.4.3用新进程替换当前进程映象
用新进程替换当前进程映像即:
用处于就绪或阻塞状态的进程来替换当前正在运行的
进程,这个功能比较容易实现,对于就绪进程替换运行进程,只就把优先级最高的就绪进程替换正在运行的进程就可以了,然后把那个运行的进程放入就绪数组中,对于阻塞进程,因为阻塞进程不能直接变为运行进程,它必须先转变为就绪进程才可以再通过进程调度变为运行进程。
所以先将阻塞进程放入就绪进程并且从阻塞数组中拿出来,再根据优先级算法和FIFO算法进程调度。
部分代码如下:
图3.6
替换前的状态:
图3.7
替换后的状态:
图3.8
3.4.4进程状态转换
在功能3中就已经实现了进程之间的转换,所以这个功能实现起来比较容易,只须依照功能三再增加几个状态转换就可以实现了。
进程的状态主要有就绪(ready)一个进程具备运行条件,但由于cpu暂时不能运行的状态(当调度给其cpu时就可以运行);等待(blocked)阻塞态或睡眠态,指进程因等待事件的发生而暂时不能运行的状态;运行(running)占有cpu,并在它上运行,故三态之间的转换是关键,须指出的是,这里的就绪变为运行状态是采用肃夺式转换的,所以不管被转换的就绪进程优先级大小,都将它执行运行操作。
部分代码如下:
图3.9
3.4.5进程调度
为了在视觉上真正达到一个进程调度的效果,我利用了一个系统函数,system(“cls”).这个函数的功能是清屏,在进程调度的时候,需要用到另外两个函数,排序和延时。
算法和思路:
首先在屏幕上输出进程的信息(包括运行时间),再调用延时函数延时一秒种左右,调用清屏函数,然后运行进程的运行时间减一,再输出进程的信息,这样就达到了一个动态的效果。
当当前进程运行完之后,再从就绪数中先择优级最高的进程执行运行操作并从就绪数组中退出,循环多次就可以达进程调度这个功能了。
利用一个变量waittimes来存放就绪进程的等待次数,每调度一次其值加一,加到三如果还没有运行,其优先级就加一,这们就可以实现每个就绪进程都有可能被运行一次。
同时,运行进程每调度一个,其优先级也减一。
部分代码如下:
图4.0
图4.1
图4.2
3.4.6上下文切换
这里的功能实现和进程调度差不多,只是在进程运行中间中断并记录它的运行时间,然后,再去运行其优先级高的就绪进程,运行完之后再切回原来的进程,这样就达到了上下文切换的功能。
核心代码如下:
图4.3
运行结果如下:
图4.4
图4.5
图4.6
3.4.7平均周转时间
这个功能主要是计算,也比较容易实现,先对就绪进程的优先级进程排序,知道它们的运行次序,然后再计算它们各自的带权周转时间,最后就可以计算出平均周转时间了。
图4.7
运行结果如下:
图4.8
3.4.8唤醒阻塞进程
将阻塞进程放入就绪数组中,并将其从阻塞数组了退出。
核心代码如下:
图4.9
运行结果如下:
图5.0
图5.1
3.4.9退出
退出程序,程序结束。
图5.2
第4章总结
通过两周的努力,虽然不能说很好,但是我却从这次的课程设计中收获了很多,获益匪浅。
无论是编程内容的深度,还是从编程技巧都有一定的意义。
让我们不仅将已经忘记的知识又重温一遍,并且上图书馆查资料,问XX、老师,掌握了新的知识!
让我们的专业知识在短时间内得到了极大的提高。
由原来的半生不熟到渐渐巩固,并且有些以前不常用的算法也用到了,在检查程序时看了高手的程序,才真正明白什么是思维的严谨,什么是细心,还有知识的重要性和实践性。
只有平时多编程,多练手,才能在最短的时间内编出最实用和最缜密满意的程序。
我经常研究其他人的程序,并不是“借鉴”,只是为了打开自己局限性。
学习他人的好的方法,为以后编程增加经验。
通过这次课程设计学到了很多,受益良多,我相信自己在这次课程设计之后,不论是个人能力方面有了很多进步。
我也会试着去向那些编程高手学习,写一些课外的程序,提高自己的编程能力,为以后的课程设计和专业知识的学习打好基础。
当然所有的努力也是为了将来毕业后从事这个行业打好基石。
最后我要谢谢朱老师,谢谢他每节课都陪着我们。
所以我在每次上机的时候都感觉,有他陪在我们身边,只要我遇到解决不了的难题,我都会得到最及时,最悉心的指导。
参考文献
[1]赵伟华等编,实用操作系统教程;机械工业出版社,2005年
[2]AbrahamSilberschatz,操作系统概念(第7版影印版);高等教育出版社,2007年
[3]GaryNutt(著),潘登(译)Linux操作系统内核实习;机械工业出版社,2004年
[4]张坤等编,操作系统教程;大连理工大学出版社,2010年
[5]李善平等译,Linux教程;清华大学出版社,2005年
[6]杨海燕等编,linux操作系统教程;清华大学出版社,2008年