对于子进程生成过程的理解

news/2024/7/20 12:30:56 标签: shell, 内存管理, 操作系统

目录

内存管理

实现shell

  生成子进程

  子进程号

  进程代码、数据、栈从何而来

  execv如何组织加工进程需要的数据

  子进程的的LDT段及LDT在GDT的段选择子

  共享打开的文件

从终端接收命令


内存管理

  说是内存管理,其实仅仅是为了实现shell、生成子进程而对内存空间简单的划分了一下。用作者的话说就是划格子,每个进程划出来1M的内存装载镜像。还有页表也都是线性映射,线性地址和物理地址都是一致的。但是不管多么简单,能达到目的就是好的设计。


实现shell

  想一想shell是什么东西?好像就是能接受用户输入的命令然后执行这个命令。那么”执行这个命名”是什么意思?就是说这个命令其实是一个程序的名字,执行它就是生成一个子进程来运行这个程序,而且这个程序要放在系统能搜索的几个路径下。

生成子进程

  为了shell接收和响应用户的一次输入后依然能够继续处理用户的下次输入,那就必须要要通过某一种方式让shell走两条分支,一条是去处理上次的用户输入,还有一条分支是继续等待用户的下次输入,如果把这两个分支全部都杂糅到给shell,恐怕逻辑会很复杂。

  我不知道当初的子进程概念是由于什么需求而引出的。但是它用来配合shell的实现是再合适不过了。我们仅仅需要在代码上安排两条分支,在进入分支之前,克隆一个子进程出来,子进程进入处理用户的的分支,而shell本身则可以继续接收用户的输入。

子进程号

  那么用什么来分流父子进程呢?也就是克隆出了一个进程后,怎么确定哪个是父进程哪个是子进程呢?这就是子进程号的功能,内核将子进程号返回给父进程,返回给子进程的却是0,所以通过这种方式,分流了父子进程逻辑。

进程代码、数据、栈从何而来

  那进程需要的数据从哪里来呢?那就是execv函数的功能了,其实shell的代码还是不复杂的,仅仅是将用户的输入用空格分隔开来,将每个字符串你的其实地址赋值给一个指针数组的相应元素。然后传给execv函数,剩下的就是execv函数的职责。

execv如何组织加工进程需要的数据

  相比较于linux 0.12来说,不用考虑太大的文件,不用考虑页表映射,更不用考虑缺页异常,仅仅是把逻辑地址加上每个进程的线性地址就是指令、数据或者栈的物理地址了。

  代码、数据:读取命令程序在硬盘上的镜像文件,然后按照elf文件的格式放到子进程空间的相应位置。

  栈:shell传递过来的是参数的指针数组,字符串本身还在另一段地址上,execv要做的就是把指针数组和字符串本身组合到一块,这样内核随后复制参数给子进程方便一些,不用一个字符串一个字符串的复制了。全部一股脑的都拿过来用就好了。

子进程的的LDT段及LDT在GDT的段选择子

  不知道大家有没有想过,用LDT来寻址,那LDT本身是在进程表里面存放的,我们克隆子进程的时候可没有克隆进程表啊,只是在进程表数组中找了一个空闲的表项给子进程用。而且克隆的时候也没有动GDT,那子进程是如何能正确运转呢?

  这又是一个鸡和蛋的问题?既然大家都相互牵扯纠缠不清,倒不人为的把最开始的状态确定下来,以便后来的流程能运转起来。

  那就提前在初始化过程中,把进程表中的LDT和GDT中LDT描述符都初始化好,等分配给子进程的时候就可以直接用了。

共享打开的文件

  还有一个问题,就是父进程打开的文件,子进程同样继承了下来,这个时候就要告诉TASK_FS了,把父进程的文件描述符的引用数都加1。


从终端接收命令

那么shell在从终端接受用户的输入时候,是如何构造指针数组的呢?

  1. 将用户的输入都读到一个缓冲区上
  2. 定义一个指针数组
  3. 按照空格分隔字符串,将每一个字符串的起始地址赋值给2中指针数组相应的位置,这样最初的栈数据就有了。到execv中只需要把两者放到一起就好了。

转载于:https://www.cnblogs.com/shangye/p/6194717.html


http://www.niftyadmin.cn/n/821329.html

相关文章

漫画 | 听说培养程序员需要从“6岁”开始...

在很多人眼中,程序员的工作就是写代码,其实现实中的程序员,除了技术硬实力之外,配套的软实力同样也至关重要!而这些软实力,恰恰能决定你职业的高度!评估能力,对工作量估计太低&#…

mysql带参数游标_如何在MySQL的存储过程中实现把过程参数用在游标定义的SELECT命令里面作为表名引用...

首先,我们来把场景描绘一下,比如下面的例子(当然是无法正确运行的):CREATE PROCEDURE proc(SourceDBName CHAR(50), SourceTableName CHAR(50),TargetDBName CHAR(50), TargetTemplateTableName CHAR(50))BEGINDECLARE done INT DEFAULT 0;DE…

【Apache RocketMQ】RocketMQ捐赠给Apache那些鲜为人知的故事-转自阿里中间件

序言 今年的双十一对阿里巴巴中间件消息团队来说,注定是个不平凡的日子。在这一天,稳定性小组重点攻克的低延迟存储解决方案成功地经受住了大考。整个大促期间,99.996%的延迟落在了10ms以内,极个别由于GC引发的停顿在50ms以内&…

一个有故事的程序员!

今天不发漫画,好好给大家介绍一下“我们”! 这里是“我们”而不是“我”,因为搞漫画真不是一个人可以干的!需要一个团队,一个不会笑的青年团队。 故事要从2个很骚的男人讲起... 我们常常说的“骚”,慢慢已经…

Docker 常用命令的使用

docker 常用命令 查找镜像 sudo docker search nginx 获取镜像 sudo docker pull ubuntu:20.04 sudo docker pull nginx 列出当前的 images $ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu 20.04 7e0aa2d69…

mysql端口13306被占用_secureCRT端口转发功能

场景:当数据库服务器放置在需要登录堡垒机才能访问的服务器时,本地程序开发如何连接到数据库呢?这里需要用到远程连接工具securityCRT或者XShell 之类,来完成端口转发的功能。secureCRT下载:链接:https://p…

css3 3D

● css3 3D旋转 ○ rotateX() 方法,元素围绕其 X 轴以给定的度数进行旋转 ○ rotateY() 方法,元素围绕其 Y 轴以给定的度数进行旋转 ○ rotateZ(angle),定义沿 Z 轴的 3D 旋转。 ● 3D景深 ○ perspective(n),景深,离屏…

python3 unicode字符串类型_Python bytes类型介绍、Python3与2字符串的区别、Python3与2编码总结...

Python bytes类型介绍Python 2 —— bytes类型1 >>> s "路飞"2 >>> prints3 路飞4 >>>s5 \xe8\xb7\xaf\xe9\xa3\x9e虽说打印的是路飞,但直接调用变量s,看到的却是一个个的16进制表示的“二进制字节”,…