进程

什么是进程?进程是一个运行中的程序实体,拥有独立的堆栈、内存空间和逻辑控制流。

这是标准的进程概念。让我们通过操作系统的fork函数看看这个抽象的概念是怎么在进程的实现中体现出来的。

构成要素

创建一个进程,需要进程体、进程表和数据空间。

进程体在C代码中对应一个函数,编译成二进制代码后就是一组指令。

进程表用来记录进程的进程ID、进程名称、寄存器快照空间。简单说,当中断发生时,会保存此刻CPU的状态,然后记录到进程表中。

进程表的作用就是用来存储进程快照。

进程堆栈的作用是什么?存储进程中函数的参数,存储进程运行过程中的局部数据。

数据空间呢?先看一段简单的代码。

char *f(int a, int b);

int main(int argc, char **argv)
{
f(5, 6); return 0;
} char *f(int a, int b)
{
int c = a + b;
char *str = "Hello, World!";
return str;
}
  1. 两个参数a和b存储在进程的堆栈中。
  2. 指针char *str指向的内存中的数据STR存储在进程的数据空间中。

为什么STR不是存储在进程的堆栈中呢?

函数f的返回值是STR的内存地址。执行这段代码,我们会发现:调用函数f能正确获得STR。

试想一下,假如STR存储在进程的堆栈中,当f执行结束后,堆栈中的数据会被清空,我们调用函数f是不能正确获得STR的。

STR存储在进程的数据空间中,存储在进程堆栈中的只是存储STR的内存空间的内存地址。

fork

进程A调用fork新建进程B,A是B的父进程,B是A的子进程。

fork执行结束后,如果能成功创建B进程,B进程的数据空间、堆栈和进程表和A进程的这些要素完全相同。

差异

B进程毕竟是不同于A进程的独立进程,所以:

  1. B进程的数据空间中的数据和A进程的数据空间的数据一致,但是,两个进程的数据空间却是不同的内存空间。
  2. B进程表中,指向LDT的选择子和A进程表中的LDT选择子不同。
  3. B进程表中的进程ID和A进程表中的进程ID不同。

堆栈

猜猜看,子进程的堆栈是在进程表中还是在数据空间中?

回答是:在进程的数据空间中。

在前面,我们虽然把堆栈和数据空间分开说,那是为了强调两个要素在保存数据时的差异。堆栈中的数据随时变化,例如,进程中的一个函数执行结束,堆栈中的数据就会发生变化。

进程的数据空间呢?我以为,当进程结束执行的时候,进程的数据空间中的数据才会消失。这是我的猜测,暂时不知道怎么去验证。

认为堆栈保存在数据空间中的依据是什么?因为寄存器ss中的选择子指向的描述符描述的那段内存空间就是数据空间。

进程的ds、es、ss的选择子相同,指向相同的数据空间。

LDT、GDT和LDT选择子

每个进程都有一个LDT。LDT存储在进程的进程表中。

在进程的进程表中,有一个LDT选择子。根据LDT选择子,能从GDT中找到指向LDT的描述符。

有点绕。连起来再说一次:通过进程表中的LDT选择子,从GDT中找到指向LDT的描述符,根据描述符找到LDT,LDT也在进程表中。

我的收获

  1. 进程的堆栈存储在进程的数据空间中。
  2. 堆栈是动态变化的,例如进程中的一个函数执行结束。堆栈中的数据容易消失,所以不能函数的返回值不能是指向堆栈的内存地址。
  3. 在函数中创建字符串变量、结构体变量,数据存储在进程的数据空间中,存储在堆栈中的只是数据的内存地址。
  4. 每个进程的堆栈栈顶可以是相同的。我的操作系统在初始化进程时,之所以使用不同的堆栈栈顶,是因为我的操作系统没有开启虚拟内存地址,使用的是相同的内存空间。如果使用相同的堆栈栈顶,不同进程的堆栈会相互覆盖。
  5. fork的实现:
    1. 子进程复制父进程的进程表,但是要使用不同的LDT选择子。
    2. 子进程要复制父进程的数据空间,同时要修改子进程的LDT。

fork、父进程和子进程的更多相关文章

  1. Linux下利用fork()创建子进程并使父进程等待子进程结束

    int status; pid_t t = fork(); if(t){     waitpid(t, &status, 0); }else{     system("vi temp ...

  2. 父进程等待子进程结束 waitpid wait

    我们一直在强调一个概念就是进程是一个程序执行的实例,是内核在虚拟概念下创建的实体,它实例化的体现在用户态就是程序代码和代码使用的变量(存储空间),在内核态就是内核为我们每个进程所保存的数据结构(状态信 ...

  3. 【LINUX】主进程、父进程、子进程、守护进程的概念

    一.摘要 详解父进程.子进程.守护进程的区别,例子稍候补充 二.定义区别 主进程 程序执行的入口,可以理解为常用的main 函数 父进程 对于子进程而言, 子进程的创造者,可有多个子进程. 任何进程都 ...

  4. linux系统编程之进程(六):父进程查询子进程的退出,wait,waitpid

    本节目标: 僵进程 SIGCHLD wait waitpid 一,僵尸进程 当一个子进程先于父进程结束运行时,它与其父进程之间的关联还会保持到父进程也正常地结束运行,或者父进程调用了wait才告终止. ...

  5. PHP多进程学习(三)__代码案例来了解父进程与子进程的执行顺序

    pcntl_fork创建子进程成功的话,系统就有了2个进程,一个为父进程,一个为子进程,父进程和子进程都继续向下执行,子进程的id号为$pid(父进程会获取子进程的$pid也就是$pid不为0,而子进 ...

  6. Linux 进程--父进程查询子进程的退出状态

    僵尸进程 当一个子进程先于父进程结束运行时,它与其父进程之间的关联还会保持到父进程也正常地结束运行,或者父进程调用了wait才告终止. 子进程退出时,内核将子进程置为僵尸状态,这个进程称为僵尸进程,它 ...

  7. swoole父进程和子进程之间通信的例子

    <?php /** 这是一个swoole父进程和子进程之间通信的例子 */ //进程创建成功后回调处理 function handle(swoole_process $worker){ //从进 ...

  8. fork新建进程——父进程等待子进程结束

    #include <sys/types.h>#include<sys/wait.h>#include<unistd.h>#include<stdio.h> ...

  9. Windows下父进程监视子进程状态

    最近研究自动化测试,需要获取程序的运行状态及结果,下面是些参考资料. 原文地址:http://blog.csdn.net/ariesjzj/article/details/7226443 Linux下 ...

随机推荐

  1. MindInsight训练可视整体设计介绍

    MindInsight训练可视整体设计介绍 MindInsight是MindSpore的可视化调试调优组件.通过MindInsight可以完成训练可视.性能调优.精度调优等任务. 训练可视功能主要包括 ...

  2. LeetCode---105. 从前序与中序遍历序列构造二叉树 (Medium)

    题目:105. 从前序与中序遍历序列构造二叉树 根据一棵树的前序遍历与中序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 例如,给出 前序遍历 preorder = [3,9,20,15,7 ...

  3. Nebula 基于 ElasticSearch 的全文搜索引擎的文本搜索

    本文首发于 Nebula Graph 公众号 NebulaGraphCommunity,Follow 看大厂图数据库技术实践. 1 背景 Nebula 2.0 中已经支持了基于外部全文搜索引擎的文本查 ...

  4. 【NX二次开发】导出x_t、导入x_t例子,UF_PS_export_data、UF_PS_import_data

    获取blockUI 体收集器选择的体,导出x_t: std::vector<TaggedObject*>objects = bodySelect0->GetSelectedObjec ...

  5. 小程序微信支付(UNIAPP+第三方SDK:binarywang)

    小程序支付流程图说明(UNIAPP+第三方SDK:binarywang) 说明:小程序为UNI-APP开发,使用的第三方微信支付SDK为binarywang提供的,此SDK对微信公众号.小程序.微信各 ...

  6. python读取csv文件数据绘制图像,例子绘制天气每天最高最低气温气象图

  7. 佛祖保佑永无BUG 神兽护体 代码注释(各种版本)

    佛祖保佑 永无BUG /* _ooOoo_ o8888888o 88" . "88 (| -_- |) O\ = /O ____/`---'\____ .' \\| |// `. ...

  8. SpringBoot缓存管理(一) 默认缓存管理

    前言 Spring框架支持透明地向应用程序添加缓存对缓存进行管理,其管理缓存的核心是将缓存应用于操作数据的方法(包括增删查改等),从而减少操作数据的执行次数(主要是查询,直接从缓存中读取数据),同时不 ...

  9. 学Java,找对圈子,跟对人

    我大学学的是机械专业,到大四才决定要学Java,以后当一名程序员. 到现在,十几年过去了,我现在已经是一家上市公司的技术总监了,管理的技术团队有100多人.很庆幸当初了选择了学Java. 还记得当初学 ...

  10. 三剑客-sed

    1.sed命令概述说明: 字符流编辑工具(行编辑工具) 2.sed命令作用说明: (1)擅长对行进行操作处理 (2)擅长将文件的信息进行修改调整/删除 3.sed具体功能 (1)文件中添加信息的能力( ...