操作系统之进程轨迹跟踪

进程是操作系统对运行的应用程序的抽象,是进行资源分配的单位。
为了更好的利用CPU,提出了多道程序设计,同时运行多个进程,交替执行,这就是并发,区别并行。
进程的基本状态分为:
这里写图片描述
还要加上推出状态,就可以了
本次实验就是跟踪这几个状态的变化。
//====================================================================================
init/main.c
kernel/fork.c
kernel/sched.c
kernel/exit.c
kernel/printk.c
这几个文件
init/main.c 需要在把log文件关联到文件描述符3 ,0 1 2分别是stdin stdout 和 stderr ,按照如下方式修改就好,同时将init()方法中这部分注释就可以了。

……
move_to_user_mode();

/***************添加开始***************/
setup((void *) &drive_info);
(void) open("/dev/tty0",O_RDWR,0);  //建立文件描述符0和/dev/tty0的关联
(void) dup(0);      //文件描述符1也和/dev/tty0关联
(void) dup(0);      //文件描述符2也和/dev/tty0关联
(void) open("/var/process.log",O_CREAT|O_TRUNC|O_WRONLY,0666);
/***************添加结束***************/

if (!fork()) {      /* we count on this going ok */
    init();
}
……

dup是一个系统调用,在unistd.h之中有定义。支持1个参数和2个参数的形式
int dup(int fd);
  int dup2(int fd1,int fd2);
  两个均为复制一个现存的文件的描述
  两个函数的返回:若成功为新的文件描述,若出错为-1;
  由dup返回的新文件描述符一定是当前可用文件描述中的最小数值。用dup2则可以用fd2参数指定新的描述符数值。如果fd2已经打开,则先关闭。若fd1=fd2,则dup2返回fd2,而不关闭它。通常使用这两个系统调用来重定向一个打开的文件描述符。
当然,大家还要知道进程0在开始的时候,就会在启动内核的时候打开文件了。
//======================================================================================================================================
之后修改kernel/fork.c kernel/sched.c kernel/exit.c 三个文件,找到进程状态转换的点,并把它输出到log文件之中。
其中fork这个东西很神奇,
声明是这样
pid_t fork(void);
pid_t 是一个宏定义,其实就是个int,定义在 #include

#include <errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <asm/segment.h>
#include <asm/system.h>

extern void write_verify(unsigned long address);

long last_pid=0;

void verify_area(void * addr,int size)
{
    ...
}

int copy_mem(int nr,struct task_struct * p)
{
   ...
}
int copy_process(int nr,long ebp,long edi,long esi,long gs,long none,
        long ebx,long ecx,long edx,
        long fs,long es,long ds,
        long eip,long cs,long eflags,long esp,long ss)
{

    p->start_time = jiffies;

    /*在上面一行初始化了进程的开始时间所以赶快输出一条进程创建的Log*/

    fprintk(3,"%ld\t%c\t%ld\n",last_pid,'N',jiffies); 
    ...
    p->state = TASK_RUNNING; /* do this last, just in case */ 
    /*在上面一行改变了进程的状态这里输出一个进入就绪队列的Log*/ 
    /*进程中Running表示的是可以运行,并不是正在运行*/
    fprintk(3,"%ld\t%c\t%ld\n",last_pid,'J',jiffies); 
    return last_pid;
}

int find_empty_process(void)
{
...
}

exit.c的修改如下:

//这里需要注意的是:进程推出的时候:先调用exit方法释放除PCB数据结构的页面  其他的所有物理页,将自己的状态置为僵尸状态,然后在通知父进程,请回收PCB所在的物理页,同时将task数据中清空为null,
对于wait系统调用不熟悉的话,请阅读:
http://blog.csdn.net/wzx19840423/article/details/6615875
博客进行相关学习
int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options)
{
    int flag, code;
    struct task_struct ** p;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值