linux内核分析 第六周 分析Linux内核创建一个新进程的过程

进程的描述

操作系统的三大管理功能:进程管理、内存管理、文件系统

为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息。

进程控制块PCB task_struct:进程状态、进程打开的文件、进程优先级信息

task_struct总体数据结构的抽象:

tty:控制台
fs:文件系统
files:文件描述符
mm:内存管理
signal:信号描述

进程的状态:

linux内核分析 第六周 分析Linux内核创建一个新进程的过程

注意:Linux下,中就绪状态和运行状态都是TASK_RUNNING

一、gdb跟踪分析一个fork系统调用内核处理函数sys_clone

linux内核分析 第六周 分析Linux内核创建一个新进程的过程

linux内核分析 第六周 分析Linux内核创建一个新进程的过程

linux内核分析 第六周 分析Linux内核创建一个新进程的过程

linux内核分析 第六周 分析Linux内核创建一个新进程的过程

二、阅读理解task_struct数据结构

linux内核分析 第六周 分析Linux内核创建一个新进程的过程
linux内核分析 第六周 分析Linux内核创建一个新进程的过程
linux内核分析 第六周 分析Linux内核创建一个新进程的过程
linux内核分析 第六周 分析Linux内核创建一个新进程的过程
linux内核分析 第六周 分析Linux内核创建一个新进程的过程
linux内核分析 第六周 分析Linux内核创建一个新进程的过程

三、创建新进程

复制一个PCB——task_struct

给新进程分配一个新的内核堆栈

修改复制过来的进程数据,如pid、进程链表

四、新进程是从哪里开始执行的

fork出来的子进程从ret_from_fork开始执行,然后跳转到syscall_exit,从系统调用中返回。

五、fork函数创建一个子进程

fork一个子进程的代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char * argv[])
{
int pid;
/* fork another process */
pid = fork();
if (pid < 0)
{
/* error occurred */
fprintf(stderr,"Fork Failed!");
exit(-1);
}
else if (pid == 0) //子进程pid == 0时返回,子进程是在内核中返回
{
/* child process */
printf("This is Child Process!\n");
}
else //父进程可以返回
{
/* parent process */
printf("This is Parent Process!\n");
/* parent will wait for the child to complete*/
wait(NULL);
printf("Child Complete!\n");
}
}

六、总结

Linux中所有的进程创建都是基于复制的方式,Linux通过复制父进程来创建一个新进程,通过调用do_ fork来实现,然后修改必要的信息,从而得到子进程的task_struck。

fork创建的新的子进程是从ret_from_fork开始执行的,然后跳转到syscall_exit,从系统调用中返回。

 
上一篇:实验六:分析Linux内核创建一个新进程的过程


下一篇:小红的难题<递推>