第六周: 进程的描述和进程的创建
Posted 吕松鸿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第六周: 进程的描述和进程的创建相关的知识,希望对你有一定的参考价值。
吕松鸿 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
一、进程的描述
1.操作系统三大功能:
进程管理
内存管理
文件系统
2.进程描述符task_struct数据结构
task _ struct:为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息。 进程的状态:Linux进程的状态(就绪态、运行态、阻塞态) 进程的标示pid:用来标示进程
3.Linux进程的状态
4.进程描述符task_struct数据结构:
struct task_struct { volatile long state; /* 进程的运行状态-1 unrunnable, 0 runnable, >0 stopped */ void *stack; /*指定了进程的内核堆栈*/ atomic_t usage; unsigned int flags; /* 每一个进程的标识符 */ int on_rq; /*运行队列*/ pid_t pid; /*进程标识符*/ struck list_head task; /*进程链表*/ /*父子进程*/ struct task_struct __rcu *real_parent; /* real parent process */ struct task_struct __rcu *parent; struct list_head children; /* list of my children */
二、进程的创建
创建进程的系统调用有3个,它们通过统一的系统调用接口进入核心态运行后就分道扬镳,各自调用自己的内核函数sys_fork、sys_clone、sys_vfork进行处理。这三个函数最终都是调用do_fork函数进行创建子进程的工作,只不过使用的参数有所不同。 Linux通过复制父进程来创建一个新进程:复制父进程PCB--task_struct来创建一个新进程,要给新进程分配一个新的内核堆栈。 修改复制过来的进程数据,比如pid、进程链表等等执行copy_process和copy_thread。 之后,从ret_from_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) { /* 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"); } }
三、实验内容
1.删除menu,下载新代码并执行。
2.gdb调试
3.设置断点
4.单步追踪
四、总结
Linux通过复制父进程来创建一个新进程:复制父进程PCB--task_struct来创建一个新进程,要给新进程分配一个新的内核堆栈。
修改复制过来的进程数据,比如pid、进程链表等等执行copy_process和copy_thread。
设置sp调度到子进程时的内核栈顶,ip转到子进程时的第一条指令地址
之后,当子进程获得CPU的控制权开始运行的时候,ret _ form _ fork可以将后面的堆栈出栈,从iret返回到用户态,从而切换到子进程的用户空间,完成新进程的创建。
以上是关于第六周: 进程的描述和进程的创建的主要内容,如果未能解决你的问题,请参考以下文章