进程的描述与创建

(一)进程的描述

(1)操作系统内核实现操作系统的三大管理功能(进程管理最为核心)

  • 进程管理

  • 内存管理

  • 文件系统

(2)在Linux内中用一个数据结构struct task_struct来描述进程,以下是其数据结构的一部分

struct task_struct {
volatile long state; //进程状态
void *stack; // 指定进程内核堆栈
pid_t pid; //进程标识符
unsigned int rt_priority; //实时优先级
unsigned int policy; //调度策略
struct files_struct *files; //系统打开文件
...
}

(3)Linux内核管理的进程状态

当使用fork()系统调用来创建一个新进程时,新进程的状态TASK_RUNNING(就绪态,但是没有运行)。当调度器选择这个新创建的进程运行时,新创建的进程就切换到运行态,它也是TASK_RUNNING。在Linux内核中,当进程是TASK_RUNNING状态时,它是可运行的,也就是就绪态,是否在运行取决于它有没有获得CPU的控制权,也就是说这个进程有没有在CPU中去实际执行,如果实际执行了,那进程状态就是运行态;如果被内核调度出去了,在等待队列里就是就绪态。对于一个正在运行的进程,调用用户态库函数exit()会陷入内核执行该内核函数do_exit(),也就是终止进程,那么会进入TASK_ZOMBIE状态,即进程的终止状态。TASK_ZOMBIE状态一般叫作僵尸进程,Linux内核会在适当的时候把僵尸进程给处理掉,处理掉之后进程描述符被释放了,该进程才从Linux中消失。一个正在运行的进程在等待特定的事件或资源时会进入阻塞态,阻塞态有两种:TASK_INTERRUPTIBLE和TASK_UNINTERRUPTIBLE,前者可以被信号和wake_up()唤醒的,后者只能被wake_up()唤醒。

(二)进程的创建

(1)0号进程的初始化

init_task为第一个进程(0号进程)的进程描述符结构体变量,它的初始化是通过听编码方式固定下来的。除此之外,所有的其他进程的初始化都是通过do_fork复制父进程的方式初始化的。

(2)用户态创建进程的方法

具体进程的创建大概就是把当前进程的描述符等相关进程资源复制一份,从而产生一个子进程,并根子进程的需要对复制的进程描述符做一定的修改,然后把创建好的子进程放入运行队列(操作系统原理中的就绪队列)。在进程调度时,新创建的子进程处于就绪状态有机会被调度执行。

 #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");
}
}

上面的代码中,else if(pid == 0)和else两段代码都被执行了,原因是因为fork系统调用把当前进程复制了一个子进程,即一个进程变成两个进程,两个进程执行相同的一段代码,但由于父进程和子进程的返回值可能不同,所以输出的信息可能不同,父进程并没有打破if else的条件分支的结构,且父子进程的执行顺序并不确定。

(三)实验跟踪分析进程创建过程

(1)首先在MenuOS中添加fork命令,编译结果如下

(2)执行fork结果如下图所示,可以看到返回了父进程和子进程

(3)接下来是设置断点,如下图所示

(4)执行一个fork发下只输出了一条就停住了,继续执行,就会看到停在的do_fork()的位置上

(5)接下来单步执行,往下执行就看到了copy_process

(6)继续执行进入dup_task_struct

(7)执行到copy_thread,继续执行就已经跟踪不到ret_from_fork,因为是汇编代码,不一定能跟踪到

(四)总结

创建一个进程是复制当前进程的信息,就是fork一个进程,这样就创建了一个新进程,因为父进程和子进程的绝大部分信息是完全一致的,但是有些信息是不能一样的,你如pid的值和内核堆栈。还有将新进程连接到各种链表中,要保存进程执行到哪个位置,有一个thread数据结构记录ip和sp等信息也不能一样,否则将会发生问题。父进程创建一个子进程,应该会有一个地方复制了父进程的进程描述符Task_struct结构体变量,并有很多地方来修改复制出来的进程描述符结构体变量。因为父子进程各自都有很多自己独立的个性,子进程应该有很多地方修改内核堆栈里的信息,因为内核兑换赞里的很多数据是从父进程复制来的,而fork系统调用在父子进程中分别返回到用户态,父子进程的内核堆栈中可能某些信息也不完全一样。还有thread,根据子进程复制的父进程的内核堆栈的状况,肯定要设定好EIP和ESP寄存器,即设定好子进程开始执行的位置,复制父进程的资源不需要修改进程资源,父子进程是共享内存存储空间的。

2019-2020-1 20199305《Linux内核原理与分析》第七周作业的更多相关文章

  1. 2019-2020-1 20199329《Linux内核原理与分析》第九周作业

    <Linux内核原理与分析>第九周作业 一.本周内容概述: 阐释linux操作系统的整体构架 理解linux系统的一般执行过程和进程调度的时机 理解linux系统的中断和进程上下文切换 二 ...

  2. 2019-2020-1 20199329《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 一.上周问题总结: 未能及时整理笔记 Linux还需要多用 markdown格式不熟练 发布博客时间超过规定期限 二.本周学习内容: <庖丁解 ...

  3. 20169212《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...

  4. 20169210《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 本周作业分为两部分:第一部分为观看学习视频并完成实验楼实验一:第二部分为看<Linux内核设计与实现>1.2.18章并安装配置内核. 第 ...

  5. 2018-2019-1 20189221 《Linux内核原理与分析》第九周作业

    2018-2019-1 20189221 <Linux内核原理与分析>第九周作业 实验八 理理解进程调度时机跟踪分析进程调度与进程切换的过程 进程调度 进度调度时机: 1.中断处理过程(包 ...

  6. 2017-2018-1 20179215《Linux内核原理与分析》第二周作业

    20179215<Linux内核原理与分析>第二周作业 这一周主要了解了计算机是如何工作的,包括现在存储程序计算机的工作模型.X86汇编指令包括几种内存地址的寻址方式和push.pop.c ...

  7. 2019-2020-1 20209313《Linux内核原理与分析》第二周作业

    2019-2020-1 20209313<Linux内核原理与分析>第二周作业 零.总结 阐明自己对"计算机是如何工作的"理解. 一.myod 步骤 复习c文件处理内容 ...

  8. 2018-2019-1 20189221《Linux内核原理与分析》第一周作业

    Linux内核原理与分析 - 第一周作业 实验1 Linux系统简介 Linux历史 1991 年 10 月,Linus Torvalds想在自己的电脑上运行UNIX,可是 UNIX 的商业版本非常昂 ...

  9. 《Linux内核原理与分析》第一周作业 20189210

    实验一 Linux系统简介 这一节主要学习了Linux的历史,Linux有关的重要人物以及学习Linux的方法,Linux和Windows的区别.其中学到了LInux中的应用程序大都为开源自由的软件, ...

  10. 2018-2019-1 20189221《Linux内核原理与分析》第二周作业

    读书报告 <庖丁解牛Linux内核分析> 第 1 章 计算工作原理 1.1 存储程序计算机工作模型 1.2 x86-32汇编基础 1.3汇编一个简单的C语言程序并分析其汇编指令执行过程 因 ...

随机推荐

  1. 改变SecureCRT的背景颜色

    1.在使用secureCRT客户端时,可以连接服务器,默认为白色底. 2.要进行对把底色的白色改为黑色的底色,右击的窗口的位置. 3.下拉菜单中点击 Session Options 4.点击Appea ...

  2. 查看yum已安装的包

    在linux下如何使用yum查看安装了哪些软件包 列出所有已安装的软件包 yum list installed yum针对软件包操作常用命令: 1.使用 yum 查找软件包 命令:yum search ...

  3. H5 app在真机调试的时候正常,打包成app后报错

    在自己的一个用h5开发的项目中, 环境 IDE HBuilderX 打包工具 Hbuilder线上打包 开发语言 JS 现象 从一个列表进入详细页之后一直转圈圈.因为是调用系统原生的等待组件,界面无法 ...

  4. 搞了一次IE浏览器兼容,我有点奔溃....

    浏览器兼容问题(主要时IE上遇到的坑坑坑) caniuse 工具(基本参考作用,实际还是需要测试) (1)安装babel-polyfill基本操作了,IE浏览器没有内置Promise对象,不仅如此,几 ...

  5. python基础实战之猜年龄游戏

    目录 一.Python基础实战之猜年龄游戏 给定年龄,用户可以猜三次年龄 年龄猜对,让用户选择两次奖励 用户选择两次奖励后可以退出 age = 18 # 答案 count = 0 # 游戏次数控制 p ...

  6. leetcode第一题两数之和击败了 98.11% 的用户的答案(C++)

    虽然题目简单,但我这好不容易优化到前2%,感觉也值得分享给大家(方法比较偷机) 题目: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们 ...

  7. ElasticSearch 时间格式

    "datetime": { "type": "date", "format": "yyyy-MM-dd HH: ...

  8. 基于vue+leaflet+echart的足迹分享评论平台

    (其实题目是随便取的,目的只是用来证明Vue+leaflet+springboot技术栈的可行性) 效果 小专栏不支持上传视频?想看的话可以去我的知乎看最新的文章,那个应该可以.在这里 主要功能描述 ...

  9. 18.JAVA-pull解析XML

    1.pull解析介绍 pull解析其实和我们上章学的sax解析原理非常类似,在Android中非常常用. 在java中,需自己获取xmlpull所依赖的类库分别为:kxml2-2.3.0.jar,xm ...

  10. Java 密码加盐

    只对密码进行md5加密很容易反推出来,另外两个用户的密码相同时,数据库保存相同的密码,知道一个用户的密码就知道另一个.解决方法是在用户的短密码后面加上一段长字符,再计算 md5,这样反推出原始密码就变 ...