标签:
进程的描述和进程的创建
一.进程的描述
(1)操作系统的三大功能:
进程管理、内存管理、文件系统
(2)进程的作用:
将信号、进程间通信、内存管理和文件系统联系起来
(3)进程控制块PCB——task_struct数据结构
提供了内核需要了解的信息
(4)task_struct结构庞大,有400多行代码。包含了进程状态、内核堆栈等相关信息的定义。
(5)Linux的进程和操作系统原理中描述的进程状态有所不同,实际内核中,就绪和运行状态都用TASK_RUNNING表示。
(6)进程标志符pid/tpid——用于标识进程
二.进程的创建
1.进程的创建概览及fork一个进程的用户态代码:
(1)进程创建的步骤:复制进程描述符;修改子进程的PCB信息
(2)shell命令如何创建子进程:
使用fork函数在用户态创建子进程;fork系统调用在父进程和子进程各返回一次;在子进程中,返回0,在父进程中,返回子进程ID。
2.理解进程创建过程复杂代码的方法:
先根据对功能的理解,自己预想可以怎样实现;再从源代码中,找到和预想相似的证据。
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和下面的else都会被执行到(一个是在父进程中即pid ==0的情况,一个是在子进程中,即pid不等于0) { /* child process */ printf("This is Child Process!\n"); } 20.else 21.{ 22./* parent process */ 23.printf("This is Parent Process!\n"); 24./* parent will wait for the child to complete*/ 25.wait(NULL); 26.printf("Child Complete!\n"); 27.} 28.}
3.浏览进程创建过程相关的关键代码
4.创建的新进程是从哪里开始执行的?
代码为:
*childregs = *current_pt_regs(); //复制内核堆栈 childregs->ax = 0; //子进程的fork返回0 p->thread.sp = (unsigned long) childregs; //调度到子进程时的内核栈顶 p->thread.ip = (unsigned long) ret_from_fork; //调度到子进程时的第一条指令地址
三、实验部分
更新menu内核,然后删除test_fork.c以及test.c
gdb调试fork命令:
qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S
设置断电:
在Menu系统中输入fork指令,可以看到只输出了fork功能的描述,在断点处sys_clone处停止了。继续运行,观察每个断点出的结果。
四、总结:
创建一个新进程的执行过程:
1.通过调用do_fork来实现进程的创建;
2.复制父进程PCB
--task_struct
来创建一个新进程,要给新进程分配一个新的内核堆栈
;
3.修改复制过来的进程数据,比如pid、进程链表等等执行copy_process和copy_thread
4、创建成功
郝智宇 无转载 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
标签:
原文地址:http://www.cnblogs.com/hzy20/p/5348340.html