Linux进程创建详解

大家好,这里是Qyynerboomer,今天为大家讲解一下Linux基础之进程创建。

一.什么是进程:

进程就是正在运行的实例,简单来说,就是程序启动后,在内存里运行的程序的副本,主要包含以下几种元素:进程控制块,代码,数据。

二.为什么会存在进程控制块:

我们的操作系统上运行着很多的进程,必须要将他们行之有效地管理起来,操作系统于是做了以下操作:设定出进程控制块,这个进程控制块中包含着有关于进程的一切信息,并将其作为一个节点纳入名为运行队列,等待队列的链表中进行管理,这样,对于进程本身的管理(如唤醒进程,阻塞进程等等)就转换成了对于各种链表的增删查改,如果我们想让一个进程运行,操作系统就会将该进程的进程控制块纳入运行队列中进行管理,如果一个进程因为io阻塞了,那么操作系统就会将其纳入阻塞队列中进行管理。

三.如何创建进程:

在Linux系统中,我们使用fork函数来创建进程,接下来我们详细讲解一下fork()函数的功能:

fork函数是在用户态(普通用户可以进入的权限受限模式)可以调用的系统调用。底层封装了内核函数do_fork()。本质上是由这个do_fork函数来完成进程的创建。进程创建这个过程本身是在内核完成的。

do_fork函数做了以下几件事情:

1.调用alloc_task_struct()函数来获得8kb的union_thread_union内存区(在内核区);用这个东西来存储进程的进程控制块和内核栈(进程是可以在用户态和内核态之间切换的,这个东西就是用来保存进程在内核态执行的临时数据)。

2.do_fork内部定义的进程指针指向父进程的进程控制块,将其完全拷贝到子进程中。

3.进行检查:当前用户所拥有的进程数量是否超过了系统给其分配资源的限制。

4.此时子进程只是复制了父进程的信息,并没有进行本身的初始化,所以子进程的状态就会被设定为TASK_UNINTERRUPTIBLE,以保证它不会马上投入运行。

5.调用get_pid函数来分配一个有效的PID(注意这个函数是一个内核函数,只能在内核里面运行,是用来分配进程PID的,我们平常学的系统调用时getpid(),是用来查询进程的PID的)。

6.子进程的东西有些是不能和父进程一模一样的,比如子进程的父进程,子进程的兄弟进程等等,这时候就要进行更新,让子进程的信息不同于父进程。

7.所有东西准备好之后,子进程的进程控制块就被插入了内核全局进程链表和pidhash哈希表。

8.把子进程PCB的状态域设置成TASK_RUNNING,并调用wake_up_process( )把子进程插入到运行队列链表。

9.让父进程和子进程平分剩余的时间片。

10.对于父进程,函数会返回子进程的pid,而对于子进程,如果子进程创建成功,那么函数就会返回0,如果创建失败,那么函数就会返回一个负值来标识错误。

以上就是进程创建的全部过程

四.一些小疑问的讲解

可能大家已经注意到,当我们完成进程的创建的时候,会将进程同时插入两个数据结构当中,一个是链表结构,一个是哈希表结构,,一个节点怎么会同时隶属于两种结构呢?这里我们就要提到Linux一个特殊的设计,将节点作为进程控制块的一部分封装进进程控制块,这听起来十分抽象,但其实非常简单:

如图所示,进程控制块里面又封装了一个新的结构体,我们来看看这个结构体内部的结构

这个函数体内部十分简洁,仅仅包含两个指针,这看起来是不是非常熟悉,这就是我们在数据结构阶段接触到的双向链表指针结构啊,所以进程控制块内部封装了很多类似的节点,包括这样的双向链表指针节点,还有运行队列,等待队列等等,所以进程控制块可以做到隶属于多个数据结构。

那么这个pidhash哈希表有什么用?

我们都知道,链表的查询效率是比较低下的,而哈希表的查询效率是很高的,如果能知道进程的pid那么几乎是O(1)的时间复杂度我们就可以查询到我们所需要的进程控制块,那么是如何做到的呢?

首先操作系统定义了这样的一个宏,传入pid,也就是x,会根据下面的规则自动计算应该插入的下标位置

复制代码
#define pid_hashfn(x) \ 
	         ((((x) >> 8) ^ (x)) & (PIDHASH_SZ - 1))

之后就根据这个位置将进程控制块节点插入就好了。

可能大家会有疑惑,这不会产生冲突吗,难道不会有两个不同的pid的值,经过了上述运算之后,得到的下标是一样的吗?这样的情况当然会出现,操作系统的设计者也早就想到了这个问题,他们给出的解决方案是这个pidhash哈希表,每个元素并不是一个单纯的进程控制块节点,而是链表结构,所以每个哈希节点都是一条链表,这样的结构还有一种名字,叫做**哈希桶;**经过运算后相同的进程控制块,就插入对应的哈希桶当中,这样就解决了冲突。

以上就是关于linux进程创建的一篇简短博文,希望对大家的操作系统学习有所帮助,大家共同进步,一同进化

相关推荐
雷电小将军5 分钟前
诡秘之主手游占卜家序列加点 诡秘之主手游占卜家怎么加点
服务器·网络·游戏·电脑·玩游戏
云飞云共享云桌面9 分钟前
苏州昆山精密机械加工厂研发部门10个SolidWorks可以部署云飞云共享云桌面吗?
大数据·运维·服务器·自动化·汽车·制造
聚美智数9 分钟前
图片水印-图片剪裁-图片缩放API接口介绍
java·服务器·数据库
wWYy.43 分钟前
Linux发送数据包的过程
linux·网络
小嵌同学1 小时前
Linux 内核中的 Per-CPU 机制详解
linux·运维·arm开发·嵌入式
云飞云共享云桌面1 小时前
自动化设备厂 10 人研发团队,如何共用一台服务器做 SolidWorks 建模?
运维·服务器·网络·3d·自动化·制造
筝筝ba1 小时前
Configure IP Address Via Different User Roles And Verify(1)
服务器
QH139292318801 小时前
NVIDIA H200 H300服务器
运维·服务器·开发语言·网络·信息与通信
xixiaoyunya1 小时前
中小微企业轻量组网方案的技术选型与实践:从传统专线到软定义隧道的成本与效能分析
服务器·php·apache
Hello-FPGA1 小时前
嵌入式LINUX 设备 ip配置后怎么保存才能掉电不消失?
linux·运维·服务器