fork、父进程和子进程
进程
什么是进程?进程是一个运行中的程序实体,拥有独立的堆栈、内存空间和逻辑控制流。
这是标准的进程概念。让我们通过操作系统的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;
}
- 两个参数a和b存储在进程的堆栈中。
- 指针
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进程的独立进程,所以:
- B进程的数据空间中的数据和A进程的数据空间的数据一致,但是,两个进程的数据空间却是不同的内存空间。
- B进程表中,指向LDT的选择子和A进程表中的LDT选择子不同。
- B进程表中的进程ID和A进程表中的进程ID不同。
堆栈
猜猜看,子进程的堆栈是在进程表中还是在数据空间中?
回答是:在进程的数据空间中。
在前面,我们虽然把堆栈和数据空间分开说,那是为了强调两个要素在保存数据时的差异。堆栈中的数据随时变化,例如,进程中的一个函数执行结束,堆栈中的数据就会发生变化。
进程的数据空间呢?我以为,当进程结束执行的时候,进程的数据空间中的数据才会消失。这是我的猜测,暂时不知道怎么去验证。
认为堆栈保存在数据空间中的依据是什么?因为寄存器ss
中的选择子指向的描述符描述的那段内存空间就是数据空间。
进程的ds、es、ss
的选择子相同,指向相同的数据空间。
LDT、GDT和LDT选择子
每个进程都有一个LDT。LDT存储在进程的进程表中。
在进程的进程表中,有一个LDT选择子。根据LDT选择子,能从GDT中找到指向LDT的描述符。
有点绕。连起来再说一次:通过进程表中的LDT选择子,从GDT中找到指向LDT的描述符,根据描述符找到LDT,LDT也在进程表中。
我的收获
- 进程的堆栈存储在进程的数据空间中。
- 堆栈是动态变化的,例如进程中的一个函数执行结束。堆栈中的数据容易消失,所以不能函数的返回值不能是指向堆栈的内存地址。
- 在函数中创建字符串变量、结构体变量,数据存储在进程的数据空间中,存储在堆栈中的只是数据的内存地址。
- 每个进程的堆栈栈顶可以是相同的。我的操作系统在初始化进程时,之所以使用不同的堆栈栈顶,是因为我的操作系统没有开启虚拟内存地址,使用的是相同的内存空间。如果使用相同的堆栈栈顶,不同进程的堆栈会相互覆盖。
- fork的实现:
- 子进程复制父进程的进程表,但是要使用不同的LDT选择子。
- 子进程要复制父进程的数据空间,同时要修改子进程的LDT。
fork、父进程和子进程的更多相关文章
- Linux下利用fork()创建子进程并使父进程等待子进程结束
int status; pid_t t = fork(); if(t){ waitpid(t, &status, 0); }else{ system("vi temp ...
- 父进程等待子进程结束 waitpid wait
我们一直在强调一个概念就是进程是一个程序执行的实例,是内核在虚拟概念下创建的实体,它实例化的体现在用户态就是程序代码和代码使用的变量(存储空间),在内核态就是内核为我们每个进程所保存的数据结构(状态信 ...
- 【LINUX】主进程、父进程、子进程、守护进程的概念
一.摘要 详解父进程.子进程.守护进程的区别,例子稍候补充 二.定义区别 主进程 程序执行的入口,可以理解为常用的main 函数 父进程 对于子进程而言, 子进程的创造者,可有多个子进程. 任何进程都 ...
- linux系统编程之进程(六):父进程查询子进程的退出,wait,waitpid
本节目标: 僵进程 SIGCHLD wait waitpid 一,僵尸进程 当一个子进程先于父进程结束运行时,它与其父进程之间的关联还会保持到父进程也正常地结束运行,或者父进程调用了wait才告终止. ...
- PHP多进程学习(三)__代码案例来了解父进程与子进程的执行顺序
pcntl_fork创建子进程成功的话,系统就有了2个进程,一个为父进程,一个为子进程,父进程和子进程都继续向下执行,子进程的id号为$pid(父进程会获取子进程的$pid也就是$pid不为0,而子进 ...
- Linux 进程--父进程查询子进程的退出状态
僵尸进程 当一个子进程先于父进程结束运行时,它与其父进程之间的关联还会保持到父进程也正常地结束运行,或者父进程调用了wait才告终止. 子进程退出时,内核将子进程置为僵尸状态,这个进程称为僵尸进程,它 ...
- swoole父进程和子进程之间通信的例子
<?php /** 这是一个swoole父进程和子进程之间通信的例子 */ //进程创建成功后回调处理 function handle(swoole_process $worker){ //从进 ...
- fork新建进程——父进程等待子进程结束
#include <sys/types.h>#include<sys/wait.h>#include<unistd.h>#include<stdio.h> ...
- Windows下父进程监视子进程状态
最近研究自动化测试,需要获取程序的运行状态及结果,下面是些参考资料. 原文地址:http://blog.csdn.net/ariesjzj/article/details/7226443 Linux下 ...
随机推荐
- MegEngine计算图、MatMul优化解析
MegEngine计算图.MatMul优化解析 本文针对天元在推理优化过程中所涉及的计算图优化与 MatMul 优化进行深度解读,希望能够帮助广大开发者在利用天元 MegEngine「深度学习,简单开 ...
- GPU上如何优化卷积
GPU上如何优化卷积 本文将演示如何在TVM中编写高性能卷积实现.我们以平方大小的输入张量和滤波器为例,假设卷积的输入是大批量的.在本例中,使用不同的布局来存储数据,以实现更好的数据局部性.缓冲区布局 ...
- CVPR2020:训练多视图三维点云配准
CVPR2020:训练多视图三维点云配准 Learning Multiview 3D Point Cloud Registration 源代码和预训练模型:https://github.com/zgo ...
- MEMS传感器作为变革的驱动力
MEMS sensors as drivers for change 物联网(IoT)正在改变与周围世界互动的方式.每个人,每件事,都是相互联系的,很快就会相互联系.微机电系统(MEMS)设备和传感器 ...
- 编译原理-一种词法分析器LEX原理
1.将所有单词的正规集用正规式描述 2.用正规式到NFA的转换算 得到识别所有单词用NFA 3.用NFA到DFA的转换算法 得到识别所有单词用DFA 4.将DFA的状态转换函数表示成二维数组 并与DF ...
- c语言经典算法---计算Fibonacci数列
算法是一个程序和软件的灵魂,作为一名优秀的程序员,只有对一些基础的算法有着全面的掌握,才会在设计程序和编写代码的过程中显得得心应手.下面我就分享一个C语言中比较基础却极为重要的一个算法----计算Fi ...
- C# —— 点击按钮动态打开ComboBox
网上搜索了好多资料,大多是重绘ComboBox或者使用自定义控件创建一个全新的ComboBox(并非基于window的ComboBox). 对于菜鸟的我,实现太麻烦,有些代码理解起来困难,但是项目比较 ...
- 你知道这高效的12个Java精品库嘛?
01. JUnit 第一个要说的当然是JUnit了,JUnit毕竟是Java圈目前最知名及常用的测试框架.JUnit之所以能够成为Java圈中最热门的测试库,是因为对于很多项目而言,单元测试是非常重要 ...
- 从架构师角度谈谈mybatis-plus可能存在的问题
存在这么一个情况:对于缺营养的人来说,医生更倾向于建议他选择纯牛奶,而不是有机奶(因其有添加剂).然而,大部分人却更加倾向于选择有机奶, 因其口感不错,因此,对于选择纯牛奶还是有机奶,这是个博弈问题. ...
- redis为什么要提供pipeline功能
通常我们用redis做接口缓存后,查询接口的性能就能提升到ms级别: 但是redis是纯内存操作啊,总不至于要到ms吧,根据官方的 benchmark 单实例也是能抗 7w+ qps 也就是说单个re ...