操作系统课程设计报告

  • 格式:docx
  • 大小:254.00 KB
  • 文档页数:15

操作系统课程设计报告

成绩:____《操作系统原理》课程设计报告

设计题目

Linux的fork.c代码的分析

Linux 的exit.c代码的分析

姓名班级学号

负责人:

参与人:

指导老师:

一、设计目的:

通过对Linux的fork.c、exit.c代码的分析, 了解一个操作系统进程的创建、退出的过程, 锻炼学生分析大型软件代码的能力通过与同组同学的合作, 锻炼学生的合作能力

二、设计步骤:

1.了解基础知识;

2.与同组同学一起讨论出任务的分配方式;

马瑞骁(计023-37):Release()函数、Sys_kill()函数、

Tell_father()函数,Sys_waitpid()函数董欣(计022-24):、Copy_progress函数,Fork.c程序流程图、

Exit.c程序流程图;

3.对自己的任务部分的代码充分阅读,注释代码,同时得到相

应的框图;

4.撰写报告。

三、设计内容:

根据课程设计指导书提供的基础知识和有关资料, 分析相关代码,

得到相关的框图, 写出设计报告。

四、设计结果:

(一)Exit.c分析:

Exit.c程序主要描述了进程终止和退出的处理事宜。主要包含进程释放、会话终止和程序推出处理函数以及杀死进程、终止进程、刮起进程等系统调用函数。还包括进程信号发送函数send_sig()和同志父进程终止的函数tell_father()。

Exit.c程序流程图:

1. Release()函数:

Release( )主要根据制定的任务数据结构(任务描述符)指针,在任务数组中删除指定的进程指针、释放相关内存页并立刻让内核重新调度任务的运行。

/*************程序分析************************/

void release(struct task_struct * p) //参数p 是任务数据结构的指针。该函数在后面的sys _ ki1l ( )和sys _waitPid ( )

中被调用。

//扫描任务指针数组表task 「」以寻找指定的任务。若

找到,则先清空该任务槽,然后释放该任务数据结构所

占用的内存页面,最后执行调度函数并在返回时立即退

出。若在任务数组表中没有找到指定任务对应的项,则

内核panic {

int i;

if (!p)

return;

for (i=1 ; i<="">

if (task[i]==p)

{

task[i]=NULL; //该任务项置空,然后释放相关的内存页。

free_page((long)p);

schedule(); //重新调度

return;

}

panic("trying to release non-existent task"); //指定任务若不存在则死机

}

/****************************************************/

Release( )程序框图如下所示: 2. Sys_kill()函数:

系统调用sys_kill( )用户向进程发送任何指定的信号。根据参数pid 的数值的不同,该系统调用会向不用的进程或进程组发送信号。

/*************程序分析************************/

int sys_kill(int pid,int sig) //参数pid 是进程号;sig是需要发送的信号。

{

struct task_struct **p = NR_TASKS + task; int err, retval = 0; if (!pid) //如果pid =0 ,那么信号就会被发送给当前进程的进程组中的所有进程。

while (--p > &FIRST_TASK)

{

if (*p && (*p)->pgrp == current->pid)

if (err=send_sig(sig,*p,1)) //强制发送信号。

retval = err;

}

else if (pid>0) //如果pid 值>0 ,则信号被发送给进程号是pid

的进程。while (--p > &FIRST_TASK) {

if (*p && (*p)->pid == pid)

if (err=send_sig(sig,*p,0))

retval = err;

} else if (pid == -1) while (--p > &FIRST_TASK) //如果pid =-1 ,则信号sig就会发送给除第一个进程外的所有进程。

if (err = send_sig(sig,*p,0))

retval = err;

else while (--p > &FIRST_TASK)

if (*p && (*p)->pgrp == -pid) //如果pid <-1 ,则信号sig将发送给进程组--sig 的所有进程。

if (err = send_sig(sig,*p,0))

retval = err;

return retval;

}

/****************************************************/ Sys_kill( )程序框图如下所示: 3. Tell_father():

该程序是通知父进程一向进程pid 发送信号sigchld :默认情况下

子进程将停止或终止。

/*************程序分析************************/

static void tell_father(int pid) { int i;

if (pid)//扫描进程数组表寻找指定进程pid ,并向其发送子进程将停止或终止信号SIGCHLD 。

for (i=0;i

p="">

{ if (!task[i])

continue;

if (task[i]->pid != pid)

continue;

task[i]->signal |= (1<<(SIGCHLD-1));

return;

}

/****************************************************/

Tell_father( )程序框图如下所示:

4. Sys_waitpid():

系统调用waitpid( )用于挂起当前进程,指导pid指定的子进程退出或者收到要求终止该进程的信号,或者是需要调用一个信号句柄。如果pid所指的子进程早已退出,则本调用将立刻返回。子进程使用的所后资源将释放。该函数的具体操作也要根据其参数进行不同的处理。

/*************程序分析************************/

int sys_waitpid(pid_t pid,unsigned long * stat_addr, int

options)

{

int flag, code;

struct task_struct ** p;

verify_area(stat_addr,4);

repeat:

flag=0;//从任务数组末端开始扫描所有任务,跳过空项、本进程项以及非当前进程的子进程项。

for(p = &LAST_TASK ; p > &FIRST_TASK ; --p) {

if (!*p || *p == current)//跳过空项和本进程项。

continue;

if ((*p)->father != current->pid)//如果不是当前进程的子进程则跳过。

continue;

if (pid>0) //如果等待的子进程号pid > 0 ,但与被扫描子进程p

的pid 不相等,说明它是当前进程另外的子进程,于是跳过该进程,接

着扫描下一个进程。

{

if ((*p)->pid != pid)

continue;

} else if (!pid) //如果指定等待进程的pid =0 ,表示正在等待进程组号等于当前进程组号的任何子进程。

{

if ((*p)->pgrp != current->pgrp)//如果此时被扫描进程p 的进程组

号与当前进程的组号不等,则跳过。

continue;

}

else if (pid != -1) //如果指定的pid <-1 ,表示正在等待进程组号等于pid 绝对值的任何子进程。

{

if ((*p)->pgrp != -pid)//如果此时被扫描进程p 的组号与pid 的

绝对值不等,则跳过。

continue;

}

switch ((*p)->state) //如果前面对pid 的判断都不符合,则表示当

前进程正在等待其任何子进程。此时所选择到

的进程p 正是所等待的子进程。

{

case TASK_STOPPED:

if (!(options & WUNTRACED))//子进程p 处于停止状态时,如果此时WUNTRACED 标志没有置位,表示程序无须立刻返

回,于是继续扫描处理其它进程。

continue;

put_fs_long(0x7f,stat_addr); //如果WUNTRACED 置位,则把状态信息ox7f 放入*stat_ addr ,并立刻返回子进程号pid 。这里Ox7f

表示的返回状态使WIFSTOPPED ( )宏为真。

return (*p)->pid;