系统软件课程设计
报告
项目名称:分析 Linux 内核--进程控制
学 号_16074301 16074304 16074323
姓 名 王宇浩 张明睿 王毅康
提交日期_________2018.12.24_________
0
成绩评定表
中期检查(成绩 10 分)
评审项目 评审内容
王宇浩
张明睿
王毅康
分值
项目 1
项目 2
项目 3
项目 4
到场,有团队合作,守纪律
任务清楚,能正确理解需求
已经完成的工作展示,工作量
达到 40%
能够有效进行过程管理【提供
相关资料证明】
最终检查展示讲解(成绩 30 分)
1
2
6
1
评审项目 评审内容
分值
项目 1
项目 2
项目 3
项目 4
项目 5
到场并进行现场讲解
能够通过 PPT、图表等方式进
行沟通、汇报和展示
讲解过程清楚明白,表现出可
以独 立完成一 个成员相应的
任务,并能进行有效的合作
可以 在合适的 时间内完成讲
解,时间利用好
对自 己相关的 部分有例子程
序运行的展示
1
6
15
3
5
王宇浩
张明睿
王毅康
最终检查回答问题(成绩 30 分)
王宇浩
张明睿
王毅康
评审项目 评审内容
项目 1
项目 2
可否口头有效沟通,可否正确
回答老师提出的问题
若为组长,评价其组长工作;
若为组员,评价其配合程度
课程设计报告(成绩 30 分)
评审项目 评审内容
项目 1
项目 2
项目 3
项目 4
报告格式符合要求【组成部分
不缺项、图表符合规范、文字
流畅没有错别字、字体大小合
理等】
图表 内容符合 计算机学科标
准
可否体会设计思路实现方案/
设计思路实现方案
是否 提交了电 子版的代码注
释或源程序
加分项目(3 分)
评审项目 评审内容
项目 1
是否使用 Git
分值
27
3
分值
6
3
18
3
王宇浩
张明睿
王毅康
王宇浩
张明睿
王毅康
分值
3
总分
教师评语:
签字:
1
目录
目录
摘要........................................................................................................................................... 3
第一部分 引言 ....................................................................................................................... 4
第二部分 进程的创建 ........................................................................................................... 5
一、 Linux 进程描述——task_struct 结构体 .................................................................. 5
二、 0 号进程和 1 号进程 ................................................................................................ 5
三、
fork()详解 ................................................................................................................. 6
第三部分 进程调用 exec() .................................................................................................. 10
一、 系统执行新程序的过程 ......................................................................................... 10
二、 exec 的实现 ............................................................................................................ 10
三、
linux_binprm ........................................................................................................... 11
四、 do_exec 的执行过程 .............................................................................................. 11
五、 文件格式、魔数和 linux_binfmt ........................................................................... 12
第四部分 进程的终止 ......................................................................................................... 13
一、 系统执行终止进程的过程 ..................................................................................... 13
二、 exit()与_exit()二者的区别 ..................................................................................... 13
三、 do_exit()函数 .......................................................................................................... 14
结束语..................................................................................................................................... 16
参考文献 ................................................................................................................................. 17
2
摘要
本次试验内容是阅读 LINUX 内核代码——进程控制相关内容,主要包括进程创建,
进程中如何执行新程序以及进程终止等,在 LINUX 内核代码中对应的主要函数或者结构
体有,task_struct,do_fork(),fo_exec(),do_exit()等,每一部分都对应进程生命周期中的
一部分,我们进行相关代码的解读与分析。
关键词:进程控制 fork exec exit
3
第一部分 引言
本次试验中,我们小组的任务是阅读 LINUX 中进程控制部分的代码,主要内容就是
阅读进程创建中的 fork()函数,在进程中执行新程序调用的 exec()函数以及进程终止的
exit()函数,从而了解在整个 LINUX 中进程的来龙去脉。我们小组一共三个人,王毅康同
学负责有关进程创建部分的内容,了解 task_struct 结构体中的内容,do_fork()函数是如何
创建进程以及 0 号 1 号进程的创建过程,张明睿同学负责理解 exec 函数的操作过程以及了
解 bprm、fmt 结构体以及魔数的内容,王宇浩同学负责 exec()部分里面六种函数的介绍以
及对于进程终止部分里 do_exit()函数以及 exit()与_exit()的区别这两部分做了重点阐述。
4
第二部分:进程的创建
一、Linux 进程描述——task_struct 结构体
task_struct 结构体中的信息主要包括两大部分:
1. 执行进程中使用的处理机硬件资源的信息
2. 进程控制中所需要的软件资源控制信息,包括进程标识符,进程状态信息,进程控
制信息等
进程的状态——volatile long state
pid_t pid 与 pid_tgid 的不同:
在 Linux 中,内核描述进程和线程都采用的是 task_struct 结构体,所以就本质上而言,
进程和线程具有相同的结构以及调度算法,所不同的是同一组线程中所有的线程共用该线程
组第一个非轻量级线程也就是创建该线程组的进程的内存空间,所以 pid 是内核为每一个进
程或者是轻量级进程打上的唯一标识,而同一组线程中他们的 tgid 是相同的都等于线程组
第一个线程的 pid,也就是说,线程组第一个线程的 pid 和 tgid 是相同的。
上述过程就是初始化一个进程的时候,为进程创建了一个空闲的 pid 之后,再初始化该
进程的 tgid=pid。
二、0 号进程和 1 号进程
0 号进程也称作 idle 进程,我粗略浅显地了解了一下 0 号进程和 1 号进程的初始化,知道了
0 号进程是唯一一个没有通过 fork()系统调用创建的进程,它也有一个 task_struct 的结构体
被定义为 INIT_TASK,当计算机启动电源后,先进程 BIOS 自检,再加载引导程序,之后内
核程序自解压和初始化一些程序,使用类似于手工的方式创建出 0 号进程,然后由 0 号进程
系统调用 fork()创建 1 号进程,开始的时候 1 号进程是运行在内核态的,它会接着完成系统
的一部分初始化,之后调用 exec()从内核态变为用户态,成为了用户空间内的第一个进程。
5
三、fork()详解
如下是 fork()的响应函数:
不同的响应函数会根据 clone_flags 的不同调用 do_fork()函数,clone_flags 用来决定祖
先进程和子进程共享的内容。
其中 sys_fork()是一般创建进程时调用的,它创建了父进程的完整副本,复制了父进程
的资源包括内存的内容和 task_struct 的内容。
Sys_clone()用来创建轻量级进程也就是线程。
Sys_vfork()创建的子进程中,父进程将自己的内存空间租给子进程使用,并且进入等待
队列,当子进程执行完后唤醒父进程。
一个问题:当父进程创建子进程后,子进程又调用 exec()去执行别的程序而丢掉 fork()为其
分配的地址空间,岂不是很浪费!
解决方案:copy_on_write(写时复制技术)和 sys_vfork()
Copy_on_write:
6
vfork():
简单来说,COW 技术就是当系统调用 fork()创建进程后,并不拷贝父进程实际的内存
数据,而是为子进程创建虚拟的空间结构,将父进程的虚拟空间复制过来,所以他们指向的
都是父进程的物理空间,当父子进程中有更改相应段的行为发生时,再为子进程分配相应的
物理空间,所以如果 fork()之后直接调用 exec()去执行另外一个程序,那么子进程就无需复
制父进程内存空间了。而 VFORK 的做法更简单粗暴,连虚拟空间都不创建了,子进程直接
共享了父进程的虚拟空间,也就共享了父进程的物理空间。
do_fork()详解
这是 do_fork()函数以及它的参数,参数解释如下:
clone_flags ——决定祖先进程和子孙进程共享的内容
stack_start ——用户状态下栈的其实地址
regs ——指向内核态堆栈通用寄存器值的指针
stack_size ——用户状态下栈的大小
7