《Linux内核--分析Linux内核创建一个新进程的过程 》 20135311傅冬菁

时间:2021-10-25 12:01:56

20135311傅冬菁

分析Linux内核创建一个新进程的过程

一、学习内容

进程控制块——PCB  task_struct数据结构

PCB task_struct中包含:

进程状态、进程打开的文件、进程优先级信息

操作系统管理的三个功能:

1.进程管理 2.内存管理 3.文件系统

Linux进程的状态:

《Linux内核--分析Linux内核创建一个新进程的过程 》 20135311傅冬菁

进程状态分析:

《Linux内核--分析Linux内核创建一个新进程的过程 》 20135311傅冬菁

long state是进程的运行状态,-1是未执行,0是执行中,大于0则是暂停;

*stack 是建立一个内核堆栈;

flags 是定义了每个进程的标识符;

《Linux内核--分析Linux内核创建一个新进程的过程 》 20135311傅冬菁

list_head tasks 这部分是定义双向链表的;

mm_struct *mm 这部分是定义内存管理中,进程的地址空间;

以上这部分代码也属于进程任务堆栈;

《Linux内核--分析Linux内核创建一个新进程的过程 》 20135311傅冬菁

定义进程的PID标识符;

《Linux内核--分析Linux内核创建一个新进程的过程 》 20135311傅冬菁

定义进程间父子的继承关系;

《Linux内核--分析Linux内核创建一个新进程的过程 》 20135311傅冬菁

与CPU相关的线程的定义;(在Linux系统中,系统将线程看作是轻量级的进程,基本上将进程和线程一视同仁)

该部分定义了线程的数据结构、文件结构、信号量等;

进程创建分析:

大部分进程都是由fork()函数创建出来的;而调用fork()函数实际上是调用了clone();

《Linux内核--分析Linux内核创建一个新进程的过程 》 20135311傅冬菁

fork()函数代码及分析:

 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 int main(int argc, char * argv[])
5 {
6 int pid;
7 /* fork another process */
8 pid = fork();//调用fork创建一个进程;
9 if (pid < 0)
10 {
11 /* error occurred */
12 fprintf(stderr,"Fork Failed!");
13 exit(-1);
14 }
15 else if (pid == 0)
16 {
17 /* child process */
18 printf("This is Child Process!\n");//创建子进程 fork系统调用在父进程和子进程各返回一次
19 }
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 }


fork、vfork和clone三个系统调用都可以创建一个新进程,而且都是通过调用do_fork来实现进程的创建。

创建新进程是通过复制当前进程实现的。do_fork主要是复制了父进程的task_struct,然后修改必要的信息,从而得到子进程的task_struct。复制一个PCB——task_struct

err = arch_dup_task_struct(tsk, orig);

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

ti = alloc_thread_info_node(tsk, node);
tsk->stack = ti;
setup_thread_stack(tsk, orig);

这里只是复制thread_info,而非复制内核堆栈要修改复制过来的进程数据,比如pid、进程链表等。

二、实验过程

《Linux内核--分析Linux内核创建一个新进程的过程 》 20135311傅冬菁

《Linux内核--分析Linux内核创建一个新进程的过程 》 20135311傅冬菁

《Linux内核--分析Linux内核创建一个新进程的过程 》 20135311傅冬菁

《Linux内核--分析Linux内核创建一个新进程的过程 》 20135311傅冬菁

《Linux内核--分析Linux内核创建一个新进程的过程 》 20135311傅冬菁

三、学习小结

1.Linux通过clone()系统调用实现fork()

2.fork(),vfork(),和clone()库函数都是根据各自需要的参数标志去调用clone(),然后由clone()调用do_fork。其中do_fork函数调用了copy_process()函数,然后让进程执行 Linux通过复制父进程创建新进程,fork、vfork、clone都是通过do_exit实现进程的创建。

3.进程创建的内容:

复制一个PCB struct

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

对子进程进行初始化,修改复制的数据。

4.父进程和子进程各返回一次。

《Linux内核--分析Linux内核创建一个新进程的过程 》 20135311傅冬菁的更多相关文章

  1. linux内核分析作业6:分析Linux内核创建一个新进程的过程

    task_struct结构: struct task_struct {   volatile long state;进程状态  void *stack; 堆栈  pid_t pid; 进程标识符  u ...

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

    潘恒 原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 task_struct结构: ...

  3. 实验 六:分析linux内核创建一个新进程的过程

    实验六:分析Linux内核创建一个新进程的过程 作者:王朝宪  <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029 ...

  4. 20135202闫佳歆--week6 分析Linux内核创建一个新进程的过程——实验及总结

    week 6 实验:分析Linux内核创建一个新进程的过程 1.使用gdb跟踪创建新进程的过程 准备工作: rm menu -rf git clone https://github.com/mengn ...

  5. 作业六:分析Linux内核创建一个新进程的过程

    分析Linux内核创建一个新进程的过程 进程描述符PCB----task_struct数据结构 操作系统:1.进程管理 2.内存管理 3 文件系统 一.新进程如何创建和修改task_struct数据结 ...

  6. Linux内核分析-分析Linux内核创建一个新进程的过程

    作者:江军 ID:fuchen1994 实验题目:分析Linux内核创建一个新进程的过程 阅读理解task_struct数据结构http://codelab.shiyanlou.com/xref/li ...

  7. Linux内核分析第六周学习笔记——分析Linux内核创建一个新进程的过程

    Linux内核分析第六周学习笔记--分析Linux内核创建一个新进程的过程 zl + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/U ...

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

    "万子恵 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 &q ...

  9. 分析Linux内核创建一个新进程的过程

    一.原理分析 1.进程的描述 进程控制块PCB——task_struct,为了管理进程,内核必须对每个进程进行清晰的描述,进程描述符提供了内核所需了解的进程信息. struct task_struct ...

随机推荐

  1. 设计模式 之 观察者(Observer)模式

    观察者(observer)模式定义了一对多的依赖关系,让多个观察者对象能够同时监听某一主题对象.这个主题对象中的状态发生改变时,就会通知所有的观察者对象. 观察者模式的结构图: 结构中各个部分的含义: ...

  2. css复习笔记

    margin: 1. 当有三个值时第一个值为上,第二个值为左右,第三个值为下. 2.margin外边距折叠,水平没有,垂直会折叠,且折叠后以两者最大值为准.另外,当一个元素包裹另一元素时也会发生折叠. ...

  3. VBA find方法

    Sub Sample() Dim sfzs As New Collection Dim ws, wbs, dbs As Worksheet Dim r As Long Set ws = ThisWor ...

  4. 非常简单的方法实现ViewPager自动循环轮播

    非常简单的方法实现ViewPager自动循环轮播,见红色代码部分,其它的代码可以忽略不看. 简洁高效是我解决问题的首要出发点. package com.shuivy.happylendandreadb ...

  5. mysql数据库连接的测试代码语句片断

    手动连接数据库 的代码片断, 用于各种数据库的测试... $conn = mysql_connect('localhost', 'root', '') or die('failed to connec ...

  6. AngularJs入门篇-控制器的加深理解基础篇

    下面做的是一个更新时间的效果,每一秒钟就会更新一下,视图中会显示出当前的时间   下面的这个例子中,SceondController函数将接受两个参数,既该DOM元素的$scope和$timeout. ...

  7. Spring Cloud Config 自动刷新所有节点 架构改造

    详细参考:<Sprin Cloud 与 Docker 微服务架构实战>p162-9.9.4节 要做的改动是: 1.在spring cloud config server 服务端加入 spr ...

  8. postman 前置 和 后置 处理器 用法

    基本用法 赋予变量 var  body="我是变量的值" ;   -----给body赋值 postman.setEnvironmentVariable("sign&qu ...

  9. Python之文件及文件系统

    open() 方法: Python open() 方法用于打开一个文件,并返回文件对象,在对文件进行处理过程都需要使用到这个函数,如果该文件无法被打开,会抛出 OSError. 注意:使用 open( ...

  10. &lbrack;C&plus;&plus;&rsqb; Swap Two Num

    Swap Two Num