Linux->父子进程初识和进程状态
目录
前言:
1. 父子进程创建
2. 进程状态
R(running)状态:
S(sleep)状态:
D(disk sleep)状态:
T(stopped)状态:
X(dead)和Z(zombie)状态:
孤儿进程:
前言:
本篇主要讲解关于关于父子进程的生成,以及利用fork生成子进程返回两个不同的返回值的概念,以及不同进程在不同反应下的状态的演示。
1. 父子进程创建
操作系统会为我们提供一些系统接口服务于我们的程序,而今天我们又会看到一个新的函数接口用于使用,那就是fork()。
这个函数的在#include<unistd.h>这个头文件当中,该函数的返回值为pid_t,也是这个头文件会为我们提供的新的类型。这个函数的作用就是会在当前进程下创建一个子进程,下面请看一个简单的程序来学习父子进程。
1 #include<stdio.h>2 #include<unistd.h>3 #include<sys/types.h>4 5 int main()6 {7 pid_t ret = fork();8 while(1)9 {10 11 if(ret == 0)12 {13 printf("我是子进程,我的PID是%d,我的PPID是%d,ret = %5d,&ret = %p。\n" 14 ,getpid(),getppid(), ret,&ret);15 sleep(1);16 }17 else18 {19 printf("我是父进程,我的PID是%d,我的PPID是%d,ret = %5d,&ret = %p。\n" 20 ,getpid(),getppid(),ret,&ret); 21 sleep(1);22 }23 //while(1)24 //{25 // printf("hello world\n");26 // sleep(1);27 //}28 }29 30 return 0;
首先咱们可以看到我们通过fork()生成了一个子进程,由ret来接收它的返回值,但是大伙可能不知道ret其实接收的不只是子进程的返回值,还有当前进程的返回值,请看下图。

可以看到父子进程的ret变量的地址是一模一样的,但是有没有发现这个地址却对应了两个值?子进程的返回值是0,而父进程是一个非0的值。
这很明显不符合我们学习这么长时间代码的规律——一个地址只能存取一个数据。那么这里是系统出BUG了吗?很显然不是的,要是这是一个BUG我也不会为大家讲解了。
那么会出现这个问题的原因其实简单来说就是,我们在程序中获取到的地址,并不是数据存储的真实位置,这是一个伪地址,操作系统会偷偷的给ret找两个存储空间,这一过程被称为写时拷贝,我会在下一篇“进程地址空间”中详细讲解,下面请先看图。

首先我们得知道进程是有独立性的,而进程又是由于内核相关的数据结构 + 代码和数据所构成,那么我们也得保证代码、数据和数据结构也的是独立得才行,所以在同一块地址需要存储两个数据时就不能放在同一块空间,从而出现写时拷贝。
从程序运行图当中,我们还能看到两个东西PID(Process ID)和PPID(Parent Process ID),也就是当前进程的ID和它的父进程ID。通过函数getpid()和getppid()可以得到。
进程ID也就相当于我们得身份证,标明这个进程存在,可以通过这个ID找到它,同时也可以通过这个ID对它进行修改等操作。
2. 进程状态
我们为了弄明白正在运行得进程时什么意思,我们需要知道进程得不同状态。一个进程可以有几个状态。请先看状态在kernel源码中的定义:
/*
* The task state array is a strange "bitmap" ofreasons to sleep. Thus "running" is zero, and *you can test for combinations of others with simple bit tests.
*/
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};
R(running)状态:
R——运行状态,我问大家一个问题,当我们的电脑中有多个软件都被运行着,那么这些软件是否在每一时刻都被CPU运行着呢?
答案是不是,还记得我们的PCB吗,CPU基于PCB去管理这些进程,而管理方式为将这些PCB结构体用特定的数据结构组织起来,例如链表方式,所以CPU在运行这些进程的时候会拿到这些进程的PCB,从而执行程序,那么此时咱们就可以联想到,CPU运行进程其实是拿到PCB,运行一会,中断,拿到下一个PCB在运行,再中断,周而复始,那么运行状态的出现其实是这个进程要么在运行,要么处于运行队列当中。

虽然这样说,但是我们是没有实际感受的,因为我们平时用电脑也没有看到一个程序一会关掉,一会又开始的情况,对此我只能说,CPU的运行速度确实厉害。
不过大家却遇到过另一个问题,那就是电脑卡死的现象,这一现象与我们下一个状态S有关。
S(sleep)状态:
在理解S状态之前我们需要先明白阻塞的概念,阻塞顾名思义,也就是当前进程没有继续推进,在等待某种资源获取成功。
那么某种资源是什么呢?举一个简单的例子大家就会懂了:
我们在网上下载游戏或者影视资源时需不需要联网?肯定是需要的,但是在下载的时候,我们将网线给他拔了,又或者是把WIFI给砸了,那么这个时候电脑处于没有网络的状态,他还能继续下载吗?当然是不能的,毕竟没有网嘛,那么此时我们的进程就在等待着网络资源,CPU就不会将他放在运行队列当中,而给它挂上S状态,让它自己去等。

我们运行的进程当中STAT下的S+就是睡眠状态,也可以叫做阻塞状态。不过大家可能有些奇怪,我不是将程序运行起来了吗?网好好的,也没个键盘输入啥的,为什么不是R状态而是S状态呢?有这个疑问的朋友可能忘记了一件事情,那就是将数据打印到显示器上有没有等待显示器准备完毕的资源信息呢?一定是有的咯,所以我们基本看不出来有程序处于R状态,一般都是在S状态。
D(disk sleep)状态:
D状态是S状态的另外一种表现形式,我们也称为不可中断睡眠状态,挂起。这个概念不好理解,我还是以讲故事的形式为大家解释。
我们有CPU,内存,磁盘三个人,某一天磁盘中有程序要运行,然后操作系统就将程序加载到内存当中,然后呢,这个程序要下载100个G的数据进磁盘当中,操作系统说:“好,你下载吧”,然后程序就呆在内存当中挂一个S状态等着。此时,电脑开了很多进程,CPU忙的不可开交,这个时候他就看到了内存里有个程序啥都不干,就在那里呆着。CPU气不过,说:“我都快要忙死了,你还在这里干扰我?去死吧你。”然后这个进程就被CPU杀死了。
这个时候,磁盘内容已经下好了,却发现找不到人来拿了,这就把磁盘急坏了,他又不敢删,但是又不知道应该把这个数据交给谁,问题就出现了。
上面的故事谁错了呢?其实它们都没有错,错的是这个世界。哈哈,开个玩笑,它们确实都没有做错,操作系统可以杀掉进程,这是它的权力,进程在等待资源,也是它的权力,而磁盘人家一直在辛辛苦苦的下载,有什么错?
其实,上面的过程究其原因不就是操作系统把进程给杀掉了,导致磁盘找不到人了吗?所以我们让进程不能被杀掉不就可以了?所以这个时候D状态就出现了。
操作系统看到进程是D状态,它就先获取这个进程的PCB,然后把这个进程退出内存,回到磁盘当中,当磁盘资源下载完毕,又将这个进程重新加载进入内存当中执行。
T(stopped)状态:
该状态表示当前停止当前的进程,直到收到继续执行的指令才会再次运行。
下面我以例子在执行:
初始运行状态

输入指令kill -19 27911,暂停父进程。运行状态,只有子进程还在执行。

此时的父进程状态也由S+变为了T。

注意,这里的子进程也由S+变为了S,这里的+表示前台运行,可以直接ctrl+c终止,但是没有+表示后台运行,需要kill杀掉进程才能终止。
X(dead)和Z(zombie)状态:
X状态是在一个进程结束之后显示的状态,这只是一个返回状态,我们不能在人物列表里面看到这个状态。
而Z状态表示当父进程和子进程都运行着,然后子进程被干掉了,此时子进程的资源还没有被系统回收,这个时候就会处于僵尸状态等待父进程去回收它。如下:

孤儿进程:
孤儿进程与僵尸状态正好相反,它是父子进程都在运行时,父进程被干掉了,此时的子进程会被init初始进程也就是1号进程收养,用于子进程结束后回收资源。如下:

看到此时的子进程的父进程变化称为了1。
以上就是我对本篇的全部理解,谢谢大伙查看。
相关文章:
Linux->父子进程初识和进程状态
目录 前言: 1. 父子进程创建 2. 进程状态 R(running)状态: S(sleep)状态: D(disk sleep)状态: T(stopped)状态: X(dead)和Z(zombie)状态: 孤儿进程: 前言: 本篇主要讲解关…...
【Linux学习笔记】5.Linux 用户和用户组管理
前言 本章介绍Linux的用户和用户组管理。 Linux 用户和用户组管理 Linux系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统。 用户的账号一方面可以…...
茂名市 2021 年高中信息技术学科素养展评
没事干,发一下去年去比赛的题目。 目录 第一题 30分 第二题 30分 第一题 30分 题目: “姐姐,乘除法运算太难了,有什么办法能熟练掌握吗?”今年 读小学四年级的表弟向李红求救。为了提高表弟的运算能力,…...
【软件测试】测试人不躺平,进军高级自动化测试自救,你的不一样结局......
目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 随着测试从业年龄的…...
win10环境下安装java开发环境安装java
一:环境介绍 安装系统版本:win10 java版本:java SE 17 二:下载Java安装包 官网下载Java安装包:Java Downloads | Oracle 中国 选择需要的Java版本进行下载,如果没有要选择的版本,可以选择最新…...
【华为OD机试模拟题】用 C++ 实现 - 开心消消乐(2023.Q1)
最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…...
opencv图像融合
大家好,我是csdn的博主:lqj_本人 这是我的个人博客主页: lqj_本人的博客_CSDN博客-微信小程序,前端,python领域博主lqj_本人擅长微信小程序,前端,python,等方面的知识https://blog.csdn.net/lbcyllqj?spm1011.2415.3001.5343哔哩哔哩欢迎关注…...
没有经验的时候,怎么搞定面试?
在之前的面试技巧,如何写简历上面,我讲了一些方法,希望大家重 视起来。核心其实就一点:他们想要你表现什么能力,以及你在 这个能力之外还有什么。 看清楚这句话的含义,你就可以做到百发百中。具体怎么训练&…...
整数保序的离散化(C/C++)
目录 1. 离散化的概念 1.1 离散化的运用思路 1.2 离散化的方法 1.2.1 排序 1.2.2 确定一个元素离散化后的结果 1.3 案例分析 1.3.1 1.3.2 区间和 (来源:Acwing) 1. 离散化的概念 离散化,把无限空间中有限的个体映射到有限的…...
python--排序总结
1.快速排序 a.原理 快速排序的基本思想是在待排序的 n 个元素中任取一个元素(通常取第一个元素)作为基准,把该元素放人最终位置后,整个数据序列被基准分割成两个子序列,所有小于基准的元素放置在前子序列中࿰…...
进化的隐藏水印:深度学习提升版权保护的鲁棒性
一、前言 过去几年,以网络视频为代表的泛网络视听领域的崛起,是互联网经济飞速发展最为夺目的大事件之一。泛网络视听领域不仅是21世纪以来互联网领域的重要基础应用、大众文化生活的主要载体,而且在推动中国经济新旧动能转化方面也发挥了重…...
Jenkins配置项目教程
在上一篇[Jenkins的使用教程](https://blog.csdn.net/weixin_43787492/article/details/129028131?spm1001.2014.3001.5501)中我介绍了如何创建一个项目 Jenkins在创建项目中提供了很多功能供我们选择,这里我将对配置项目做一个较完整的介绍Jenkins配置项目0、所有…...
C++多继承,虚继承部分总结与示例
tags: C OOP 写在前面 写一下多继承, 虚继承的一些部分, 包括一些例子. 多继承 简介 多继承是指从多个直接基类中产生派生类的能力. 多继承的派生类继承了所有父类的属性, 所以会带来一些复杂的问题. 示例1: 多继承用法与调用顺序 #include <string> #include <…...
程序员35岁以后就没有出路了吗?听听京东10年测开的分析
国内的互联网行业发展较快,所以造成了技术研发类员工工作强度比较大,同时技术的快速更新又需要员工不断的学习新的技术。因此淘汰率也比较高,超过35岁的基层研发类员工,往往因为家庭原因、身体原因,比较难以跟得上工作…...
数据结构(六):冒泡排序、选择排序、插入排序、希尔排序、快速排序
数据结构(六)一、大O表示法二、冒泡排序三、选择排序一、大O表示法 在计算机中采用粗略的度量来描述计算机算法的效率,这种方法被称为“大O”表示法。 我们判断一个算法的效率,不能只凭着算法运行的速度,因为随着数据…...
C++之类与对象(上)
目录 一、类的定义 二.类的访问限定及封装 1.访问限定 2.封装 三.类的作用域和实例化 2.类的实例化 四.类的对象大小的计算 1.类成员存储方式 2.结构体内存对齐规则 五.类成员函数的this指针 1.this指针的引出 2.this指针的特性 3.C语言和C实现Stack的对比 一、类的定义 class …...
Java岗面试题--Java并发 计算机网络(日积月累,每日三题)
目录1. 面试题一:在 Java 程序中怎么保证多线程的运行安全?1.1 追问一:Java 线程同步的几种方法?2. 面试题二:JMM3. 面试题三:计算机网络的各层协议及作用?1. 面试题一:在 Java 程序…...
三菱FX3U与威纶MT8071IP走RS422通讯
一、准备工作 1.需要工具: 电脑一台、PLC:三菱FX3U一个、触摸屏:威纶MT8071一个、 (三菱圆形编程口转USB)一根、触摸屏与电脑通讯线一根(T型口数据线)、PLC与触摸屏通讯线:电烙…...
给想考CISP的一点建议
如果你正在考虑参加CISP认证考试,以下是我对你的几点建议: 了解CISP考试: 在报名参加考试之前,要充分了解CISP认证考试的考试内容、考试形式、考试难度等相关信息,这有助于你制定更有效的备考计划。制定备考计划&…...
ACM 记忆化搜索
一.记忆化搜索概述 1.概念 搜索是一种简单有效但是效率又很低下的算法结构,其低效的原因主要在于存在很多重叠子问题。而记忆化搜索则是在搜索的基础上,利用数组来记录已经计算出来的重叠子问题状态,进行合理化的剪枝,从而降低时…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...
Python 实现 Web 静态服务器(HTTP 协议)
目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1)下载安装包2)配置环境变量3)安装镜像4)node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1)使用 http-server2)详解 …...
Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...
Kafka主题运维全指南:从基础配置到故障处理
#作者:张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1:主题删除失败。常见错误2:__consumer_offsets占用太多的磁盘。 主题日常管理 …...
