操作系统课程设计报告
- 格式: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;