您的位置:首页 > 其它

操作系统课程实验报告(四)

2017-07-29 22:39 381 查看


进程运行轨迹的跟踪和统计——还是李老师那门课的实验,把它从实验楼搬过来了。

报告正文

这个实验的目的:需要在linux 0.11中建立一个log文件用来收集linux
0.11 运行中所有进程创建、切换以及退出的状态。为此,我们需要在系统初始化的时候建立一个log文件,用来记录;需要一个 fprintk
函数,它可以向log文件写入进程各种状态;需要在所有控制进程的函数当中加入 fprintk
函数的调用,以写入log文件。
首先,修改linux 0.11让它在初始化的时候能够产生一个log文件,只需要修改init/main.c,这里几条语句的顺序不能颠倒,我们将来需要用文件描述符3来指向log文件,写入进程信息。



把已经写好的fprintk放入kernel/printk.c中,这个步骤按照实验提示进行即可。
接下来,我们需要在有关进程的各个调用当中,加入fprintk,使得系统进程发生改变的时候可以向log文件写入一些信息。我认为,这个部分顺着一个进程由被创建到最后退出的过程来思考各种状态切换,会比较清晰。
一个进程声明周期,是由fork函数开始的。fork函数所做的事情,就是将中断调用了sys_fork,然后由sys_fork调用copy_process,copy_process会把父进程运行状态当中的各种参数(内核栈的内容)复制一份,放进一个新建的PCB中,作为新的子进程的PCB使用。注意,fork并不负责切换,它只负责创建一个跟父进程差不多一模一样的子进程,放在就绪队列中等待被切换。一旦PCB搞定了,放到就绪队列中了,就没有fork什么事了。所以,我们需要跟进一个进程的建立,就需要在copy_process(在kernel/fork.c中)中加入fprintk函数调用,并且表明两种状态,一是‘N’,表示有一个新进程;二是‘J’,表示有这个进程已经放入就绪队列,等待被切换。



当一个进程进入了就绪队列,那么它就可能被切换运行,切换的操作由schedule函数(在kernel/sched.c中)进行,这里有两个地方需要注意:第一,切换可能由一个正在运行中的进程切回到它自己,这个进程的状态实际上没有变化,所以schedule需要判断当前进程和将要切换的下一个进程是不是同一个家伙,如果是,那就不需要输出状态了,因为没有变化;第二,需要了解当前进程是因为什么而被切换,这决定了它的状态是被切成‘J’还是‘W’,因为当进程睡眠时也会调用schedule,它并非进入就绪队列而是进入阻塞队列。



这个运行中的进程,有可能会进入睡眠状态,这就是运行到睡眠的切换,通过几个调用来实现:
sys_pause(在kernel/sched.c中)



sys_waitpid(在kernel/exit.c中)



不可中断睡眠 sleep_on(在kernel/sched.c中)



可中断睡眠 interruptible_sleep_on(在kernel/sched.c中)



这里需要注意的是sys_pause和两个睡眠。
系统在无事可做的时候会不断调用sys_pause,所以如果不加一个条件判断会造成不断输出0号进程的‘W’状态的情况。
另外,睡眠进程唤醒顺序是反向的,从最后一个睡眠的进程开始到第一个睡眠的进程。除了最后一个进程是被wake_up或者信号唤醒,其余的都是通过tmp来唤醒的。所以需要在tmp所指向的进程状态改变为0时输出‘J’,因为它从阻塞队列进入就绪队列。
进程睡眠后,需要通过信号(在schedule中)或者wake_up(在kernel/sched.c中)唤醒,修改如下:





上面已经谁完了进程的创建,以及就绪切运行,运行切就绪,运行切睡眠和睡眠切就绪的状态,最后只需要再输出进程退出的状态就可以了。通过修改,do_exit(在kernel/exit.c中)



修改完成了,make all一下重新编译,就可以跑虚拟机了。
在虚拟机下面运行自己写的process.c





可以看到父进程id是8,子进程id分别是9/10/11/12,将log文件放到自己的ubuntu上,运行python程序分析
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  操作系统