进程的描述
操作系统的三大管理功能:进程管理、内存管理、文件系统
为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息。
进程控制块PCB task_struct:进程状态、进程打开的文件、进程优先级信息
task_struct总体数据结构的抽象:
tty:控制台
fs:文件系统
files:文件描述符
mm:内存管理
signal:信号描述
进程的状态:
注意:Linux下,中就绪状态和运行状态都是TASK_RUNNING
一、gdb跟踪分析一个fork系统调用内核处理函数sys_clone
二、阅读理解task_struct数据结构
三、创建新进程
复制一个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
,从系统调用中返回。