当前位置: 首页 > news >正文

【Linux】进程理解与学习(Ⅱ)

环境:centos7.6,腾讯云服务器
Linux文章都放在了专栏:【Linux】欢迎支持订阅🌹
相关文章推荐:
【Linux】冯.诺依曼体系结构与操作系统
【Linux】进程理解与学习(Ⅰ)
浅谈Linux下的shell--BASH

前言

章节介绍

在前文中我们已经了解了进程的相关概念,明白了OS管理进程实际上就是对进程对应的task_struct/pcb做相关操作,但是实际上系统中存在的进程有很多,我们可以输入指令ps -lA 查看当前系统下的所有进程。而OS为了更高效的对进程进行管理,不会对每个进程都面面俱到,而是会将进程分为不同的状态这就好像OS为了更好的管理内存,会将内存划分为不同的分区,每个分区存放各自对应的数据类型,比如栈区存放一些局部变量、静态区存放全局变量等)从而来进行更好的管理

本次章节目标就是对进程的不同状态做相关介绍与深入了解

ps -lA查看系统下的所有进程(部分)

阻塞与挂起

阻塞

在了解进程状态之前,我们先来谈一谈阻塞与挂起的两个概念。所谓阻塞,就是指进程因为等待某种资源就绪,而导致的一种不推进状态。也就是我们常说的卡住了。

🔺这里简单举个例子

  • 就好比我们在下载一些东西时假如突然断网,那我们的下载是不是就停住了,然后等网络资源恢复后才可以继续进行下载。而这个停住的过程,就是阻塞。实际上本质来说就是pcb此时本应被cpu调度,执行下载,但是因为网络资源突然断开,此时pcb就会到网络资源对应的pcb队列中排队等待,等到网络资源就绪,并且排到它时,它才会继续回到运行队列排队,然后等待被cpu调度,继续下载。

分析图

当然,为了更直观的看到这种现象,我们可以看下面这张图

分析图2

挂起

  • 挂起本质也是一种特殊的阻塞,挂起是一种什么情况呢?我们前文已经了解了,进程=内核数据结构(pcb)+进程的代码与数据。而挂起实际上是指:该进程的pcb没有被cpu调度,然后占用了内存空间,此时OS会将该进程的数据与代码放到磁盘中暂存,等pcb被调度时,再将代码和数据预加载到内存。

★简单总结

  • 进程的pcb可以被维护在不同的队列

  • 阻塞:进程因为等待某种资源,而导致的不推进状态(pcb会到某种资源的等待队列下排队,等资源就绪时再被维护到运行队列,等待调度)

  • cpu的调度一般是一种线性调度(当然也存在因为进程优先级而导致的插队情况,后面会讲)

  • 挂起是一种特殊的阻塞,pcb不被cpu调度,os会将数据与代码暂存在磁盘,等pcb进入运行队列等待调度时,再将数据与代码预加载到内存。

进程状态

我们可以查看内核中的源码,来看看进程的各种状态

/*
* The task state array is a strange "bitmap" of
* reasons 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)

R表示该进程处于一种运行状态,不过这里需要注意的是,R状态表示的运行是指只要进程的pcb在运行队列下,都是R,并不是说一定是指在cpu上运行。

我们看一下以下代码:

 #include<stdio.h>int main(){while(1){printf("hello world,pid:%d\n",getpid());                                                                                                                    }                                                                           return 0;                                                                   } 

运行结果与疑惑

S表示的是可中断休眠状态,为什么不是R状态呢?实际上确实如我们所说,我们的程序一直在运行,但是,cpu调度的速度实在是太快了,我们很难捕捉到,并且pcb相对于被cpu的调度时间,其余99%的时间都用在了在外设(显示器)的等待队列中排队了。所以,我们可以看到程序在不断打印数据在显示器,但是却捕捉不到cpu调度pcb并执行的那一刻。

不过我们假如将外设这个干扰给屏蔽了,如下:

#include<stdio.h>int main(){while(1){}return 0;} 

小总结一下

  • 只要处在运行队列下,就是R状态(所以我们有时可能会发现多个进程处于R状态,也不足为奇,这不是指它们同时被调度,而是指它们都处在运行队列,等待被cpu调度)

可中断休眠状态(S)

正如上面的图片所示,我们看到S状态是因为程序的pcb99%的时间都在外设的等待队列下排队而被cpu调度的那一刻我们捕捉不到。这里大家有没有发现,休眠状态与我们的上面讲的阻塞状态一致,阻塞就是指pcb不被cpu调度,去某个资源的队列下等待资源就绪。

事实上确实如此,S状态的本质就是阻塞。(pcb去某种资源的等待队列下排队,等待资源就绪)。至于说它是可中断休眠,是因为我们可以通过ctrl c或者kill命令来结束该进程。

  • (可以这么来说: S状态就意味着进程在等待事件完成(等待资源就绪),并且这种状态是可以被我们使用指令来中断。

可中断休眠

不可中断休眠状态(D)

所谓不可中断休眠状态,说白了就是我们不可以使用kill、ctrl c等命令将进程中断,我们只可以将电源关闭,以此来结束进程,但是这样做可能会造成数据的丢失等问题。(这种状态一般很难看到)

暂停状态(T)

暂停状态顾名思义就是让该进程暂停,我们可以通过指令kill -19 pid的指令来暂停该进程。输入指令kill -18 pid可以使该进程继续运行。

(不过需要注意的是,当恢复运行时,此时的进程就处于后台进程,我们用ctrl c结束不了,用kill指令才可以中止进程,关于前后台进程我会在后面的章节讲解。)

如下:

死亡状态(X)

  • 这个状态只是一个返回状态,表示该进程已经彻底结束。我们不会在任务列表里看到这个状态。

僵尸状态(Z)

返回代码

我们每一个进程结束时都会有一个退出码,就好像我们写一个main函数时,最后都会加上return 0,return 0就表示该进程正常返回(事实上就算我们不写return 0,系统也会默认return 0),这里的0就是该进程的返回代码

(Linux下可以通过echo $?指令来查看该进程的返回代码)

vs下编译后的返回代码

僵尸状态(Z)

僵尸状态是指一个进程结束时,它的返回代码没有被父进程读取,那么该进程会一直处于一种僵尸状态,等待父进程读取,直到父进程读取返回结果后,才彻底结束子进程。

保持僵尸状态是为了让父进程读取该进程的返回代码,而我们平常写的程序为什么结束后没有变成僵尸呢?

  • 这是因为他们的父进程是bash(不理解的可以看前面的章节,有讲到bash下运行的程序的父进程都是bash),而bash有回收机制,所以我们写的程序运行结束后会被bash的回收机制回收。我们也就观察不到僵尸进程。

不过我们可以写以下代码,用fork创建子进程,来观察僵尸状态:

 #include<stdio.h>#include<unistd.h>int main(){//fork创建子进程pid_t id=fork();if(id == 0){//childwhile(1){printf("子进程:pid:%d,ppid:%d\n",getpid(),getppid());sleep(1);}}else{//fatherwhile(1){printf("父进程,pid:%d,ppid:%d\n",getpid(),getppid());sleep(1);}}return 0;                                                                                                                }  

此时我们kill -9 进程pid结束子进程,观察子进程是否立马结束,还是如我们所说维持僵尸状态,等待父进程读取推出结果。通过以下运行结果可以发现,子进程并不是直接退出

运行结果

僵尸状态的危害
如果一个进程处于Z状态,假如它的父进程一直不读取该进程的退出码,那么该进程会一直维持僵尸状态。而维护这个状态,实际上就是维护这个数据,该数据也属于进程基本信息,保存在task_struct(PCB)中,不仅占用了内存空间(因为task_struct本身是一个结构体,结构体都会有自己的大小),并且维护pcb也是有一定的代价的。

★简单总结一下

  • R状态是指该进程的pcb处在运行队列,而不是一定要在cpu上运行

  • pcb被cpu调度运行的时间,远远远远快于pcb在资源的等待队列下等待资源就绪的时间

  • S与D的区别在于是否可以通过kill或者ctrl c来人为中止进程,但两者本质都是阻塞

  • kill -19 PID 暂停进程,kill -18 PID恢复进程(恢复后的进程属于后台进程,不可ctrl c中止,可以kill -9 PID中止)

  • 暂停状态实际上也是阻塞(要等待你发出指令继续运行)

  • 僵尸状态是指子进程退出时,退出结果没有被父进程读取,子进程就会保持僵尸状态,直到父进程读取返回结果,才彻底结束

  • bash有回收机制,所以我们写的程序运行结束后,不会变成僵尸,会被bash的回收机制回收

  • 僵尸进程会占用空间资源,造成资源泄露,具有一定的危害性,具体避免方式以后再细谈

孤儿进程

我们上面讲了子进程退出时不会立马退出,而是维持僵尸状态等待父进程读取退出结果。(如果父进程是bash,则会被bash的回收机制回收,不会出现僵尸)

那么假如子进程正常运行,父进程结束呢?如下:

杀掉父进程,发现子进程的父进程变成了1号

这里我们来分析一下,为什么父进程结束后不会出现僵尸呢?

  • 答:因为该父进程的父进程为bash,退出结果被bash的回收机制回收了,所以父进程没出现僵尸。

为什么该父进程的子进程被1号进程领养了呢?1号进程是什么?

1号进程实际上就是操作系统

  • 答:父进程退出,子进程被操作系统领养(通过让子进程的父进程变成1号进程),此时的子进程就是孤儿进程。被领养是为了读取子进程的退出结果。(假如没有被领养的话,子进程的退出结果就不会有人能拿到,那么子进程就成了僵尸,会一直存在,造成内存泄漏。这是OS不允许的,所以会让1号进程成为子进程的父进程,从而拿到子进程的退出结果)。


end.

生活原本沉闷,但跑起来就会有风!🌹

相关文章:

【Linux】进程理解与学习(Ⅱ)

环境&#xff1a;centos7.6&#xff0c;腾讯云服务器Linux文章都放在了专栏&#xff1a;【Linux】欢迎支持订阅&#x1f339;相关文章推荐&#xff1a;【Linux】冯.诺依曼体系结构与操作系统【Linux】进程理解与学习&#xff08;Ⅰ&#xff09;浅谈Linux下的shell--BASH前言章节…...

vscode 爽到起飞的快捷键

这里写目录标题1. 窗口操作2. 代码编辑3. 批量操作4. 错误处理1. 窗口操作 文件之间切换: CtrlTab 切出一个新的编辑器窗口&#xff08;最多3个): Ctrl\ 切换左中右3个编辑器窗口的快捷键: Ctrl1 Ctrl2 Ctrl3 2. 代码编辑 代码格式化: ShiftAltF 向上或向下移动一行: Alt…...

vs +qt 打包.cpp和.h为DLL文件

文章目录一 编译成库1 创建一个Qt library 项目2&#xff0c;将已有的文件拷贝到项目目录下3 在项目中添加现有项4&#xff0c;拷贝头文件到需要暴露给外面使用的类的头文件中5 拷贝xxx_EXPORT的宏到需要被暴露的类的名前面6 然后点击编译 就完成了。得到的dll文件在debug里面二…...

echarts有滑块

vue下使用echarts折线图及其横坐标拖拽功能 drawLine() {let that this,lineDate [],dispatchCount [],finishCount [],newCount [];let param {// 参数};axios.post(url, param).then(function(response) {let rs response.data.data;if (rs ! undefined && rs…...

MATLAB绘制ROC曲线

ROC曲线(Receiver Operating Characteristic Curve) 1 简介 ROC曲线是用于评估二元分类模型&#xff08;如Logistic回归&#xff09;表现优劣的一种工具&#xff0c;其横轴表示假阳性率&#xff08;false positive rate&#xff0c;FPR&#xff09;&#xff0c;即实际为负例但…...

ChatGPT前传

文章目录前言GPT概述GPT-1代GPT-1 学习目标和概念介绍GPT-1 训练数据集GPT-1 模型结构和应用细节GPT-1 效果性能和总结GPT-2代GPT-2 学习目标和概念介绍GPT-2 训练数据集GPT-2 模型结构和应用细节GPT-2 性能效果和总结GPT-3代GPT-3 学习目标和概念介绍GPT-3 训练数据集GPT-3 模…...

我的十年编程路 2020年篇

我出生在1990年&#xff0c;2020年到来的时候&#xff0c;我完成了一项成就&#xff1a;奔三。同时&#xff0c;也开启了新的征程&#xff1a;奔四。 2020年的春节是在广州的丈母娘家度过的&#xff0c;春节后大概是初五&#xff0c;或者是初六&#xff0c;我和媳妇就返回天津…...

力扣-SQL【入门】

https://leetcode.cn/study-plan/sql/?progressxhqm4sjh 目录选择595. 大的国家1757. 可回收且低脂的产品584. 寻找用户推荐人183. 从不订购的客户排序 & 修改1873. 计算特殊奖金627. 变更性别196. 删除重复的电子邮箱选择 595. 大的国家 # Write your MySQL query state…...

Vue中组件到底是什么

1.先说结论&#xff1a; Vue中组件本质是一个名为VueComponent的构造函数&#xff0c;且不是程序员定义的&#xff0c;是Vue.extend生成的。 2.我们使用组件时发生了什么&#xff1f; 比如定义了一个school,然后在页面上使用它 我们只需要写 < school/ > 或< school &…...

不同时间间隔数据对统计结果的影响

目录摘要1. 实测数据来源2. 数据分析方法3 结果分析3.1 波况分析摘要 采用不同的波浪观测方法所获得的波浪数据的时间间隔不一致&#xff0c;其数据的准确性须进行分析。基于大埕湾逐时周年波浪观测数据&#xff0c;截取不同时间间隔的波浪数据&#xff0c;采用统计和相关分析…...

hudi系列-数据写入方式及使用场景

hudi支持多种数据写入方式:insert、bulk_insert、upsert、boostrap,我们可以根据数据本身属性(append-only或upsert)来选择insert和upsert方式,同时也支持对历史数据的高效同步并嫁接到实时流程。 这里的使用技术组合为flink + hudi-0.11 upsert 这是hudi默认的写入方式,…...

C # FileStream文件流

本章讲述&#xff1a;FileStream类的基本功能&#xff0c;以及简单示例&#xff1b; 1、引用命名空间&#xff1a;using System.IO; 2、注意&#xff1a;使用IO操作文件时&#xff0c;要注意流关闭和释放问题&#xff01; 强力推荐&#xff1a;将创建文件流对象的过程写在usi…...

Go语言中的保留字和运算符详解

前言 &#x1f3e0;个人主页&#xff1a;我是沐风晓月 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是沐风晓月&#xff0c;双一流院校计算机专业&#xff0c;阿里云博客专家 &#x1f609;&#x1f609; &#x1f495; 座右铭&#xff1a; 先努力成长自己&#xff…...

Linux编译之(1)C语言基础

Linux编译之C语言基础 Author&#xff1a;Once Day Date&#xff1a;2023年3月11日 漫漫长路&#xff0c;才刚刚开始… 1.概述 在Linux下开发多源文件的C代码文件&#xff0c;是一定要了解Makefile的&#xff0c;虽然现在构建工具很多&#xff0c;但学习的一开始&#xff0…...

CPU平均负载高问题定位分析

一、Linux操作系统CPU平均负载 1.1什么是CPU平均负载 1.2 怎么查看平均负载数值 二、Linux操作系统CPU使用率和平均负载区别 CPU使用率和平均负载区别 三、阿里云Linux操作系统CPU压测环境准备 3.1 核心命令应用场景 3.2 模拟生产环境出现的多种问题环境准备 分析工具安…...

Python蓝桥杯训练:基本数据结构 [二叉树] 中

Python蓝桥杯训练&#xff1a;基本数据结构 [二叉树] 中 文章目录Python蓝桥杯训练&#xff1a;基本数据结构 [二叉树] 中一、[翻转二叉树](https://leetcode.cn/problems/invert-binary-tree/)二、[对称二叉树](https://leetcode.cn/problems/symmetric-tree/)三、[二叉树的最…...

读取 DTC 信息服务 (0x19) – UDS 协议

总目录链接>> AutoSAR入门和实战系列总目录 0x19读取 DTC 信息服务概述 读取 DTC 信息服务在 UDS 协议中用于从车辆或特定 ECU 或节点读取 DTC。UDS 协议的主要任务之一是故障诊断。每当车辆发生任何故障时&#xff0c;与该故障相对应的诊断故障代码&#xff08;DTC&a…...

Hive 分区表新增字段 cascade

背景 在以前上线的分区表中新加一个字段&#xff0c;并且要求添加到指定的位置列。 模拟测试 加 cascade 操作 创建测试表 create table if not exists sqltest.table_add_column_test(org_col1 string comment 原始数据1,org_col2 string comment 原始数据2 ) comment 增…...

【Java版oj】day08两种排序方法、最小公倍数

目录 一、两种排序方法 &#xff08;1&#xff09;原题再现 &#xff08;2&#xff09;问题分析 &#xff08;3&#xff09;完整代码 二、最小公倍数 &#xff08;1&#xff09;原题再现 &#xff08;2&#xff09;问题分析 &#xff08;3&#xff09;完整代码 一、两种…...

FinOps,从概念到落地 | UGeek大咖说第一期直播回顾(上)

2023年2月28日&#xff0c;由优维科技联合FinOps产业推进方阵举办了第1期「UGeek大咖说-极致用云共济FinOps」线上直播活动&#xff0c;来自中国信通院及美图公司技术专家共同带来了一场精彩的技术视听盛宴。 直 播 背 景 目前&#xff0c;许多以“上云”为数字化转型路径的企…...

k8s java程序实现kubernetes Controller Operator 使用CRD 学习总结

k8s java程序实现kubernetes Controller & Operator 使用CRD 学习总结 大纲 原理Controller 与 Operator自定义资源定义 CRD ( CustomResourceDefinition)kubernetes-client使用java fabric8io/kubernetes-client操作k8s 原生资源使用java abric8io/kubernetes-clientt操…...

Unity笔记:修改代码执行的默认打开方式

使用 External Tools 偏好设置可设置用于编写脚本、处理图像和进行源代码控制的外部应用程序。 External Script Editor&#xff1a;选择 Unity 应使用哪个应用程序来打开脚本文件。Unity 会自动将正确的参数传递给内置支持的脚本编辑器。Unity 内置支持 Visual Studio Commun…...

Linux IPC:匿名管道 与 命名管道

目录一、管道的理解二、匿名管道三、命名管道四、管道的通信流程五、管道的特性进程间通信方式有多种&#xff0c;本文介绍的是管道&#xff0c;管道分为匿名管道和命名管道。 一、管道的理解 生活中的管道用来传输资源&#xff0c;例如水、石油之类的资源。而进程间通信的管道…...

阿里研发工程师JAVA暑期实习一面

文章目录先说一下我自己的情况面试过程总结先说一下我自己的情况 我就读于湖南大学&#xff0c;软件工程专业&#xff0c;现在大三下 很巧的是&#xff0c;我在大二的时候就在相同的时间面过相同的部门和相同的岗位&#xff0c;所以我没有做笔试就直接让我去面试了。我当时还纳…...

第十四届蓝桥杯三月真题刷题训练——第 11 天

目录 第 1 题&#xff1a;卡片 题目描述 运行限制 第 2 题&#xff1a;路径_dpgcd 运行限制 第 3 题&#xff1a;字符统计 问题描述 输入格式 输出格式 样例输入 样例输出 评测用例规模与约定 运行限制 第 4 题&#xff1a;费用报销 第 1 题&#xff1a;卡片 题…...

机器学习入门——线性回归

线性回归什么是线性回归&#xff1f;回归分析&#xff1a;线性回归&#xff1a;回归问题求解单因子线性回归简单实例评估模型表现可视化模型展示多因子线性回归什么是线性回归&#xff1f; 回归分析&#xff1a; 根据数据&#xff0c;确定两种或两种以上变量间相互依赖的定量…...

Microsoft Word 远程代码执行漏洞(CVE-2023-21716)

本文转载于&#xff1a; https://mp.weixin.qq.com/s?__bizMzI5NTUzNzY3Ng&mid2247485476&idx1&sneee5c7fd1c4855be6441b8933b10051e&chksmec535547db24dc516d013d3d76097e985aaad7f10f82f15b4e355a97af75fd333acdab6232af&mpshare1&scene23&srci…...

Android kotlin 系列讲解(数据篇)SharedPreferences存储及测试

文章目录 一、什么是SharedPreferences1、将数据存储到SharedPreferences中2、从SharedPreferences中读取数据二、登录使用SharedPreferences一、什么是SharedPreferences SharedPreferences是使用键值对的方式来存储数据的。也就是说,当保存一条数据的时候,需要给这条数据提…...

一文了解Web Worker

一、概述 众所周知&#xff0c;JavaScript最初设计是运行在浏览器中的&#xff0c;为了防止多个线程同时操作DOM带来的渲染冲突问题&#xff0c;所以JavaScript执行器被设计成单线程。但是随着前端技术的发展&#xff0c;JavaScript要处理的工作也越来越复杂&#xff0c;当我们…...

接口文档包含哪些内容?怎么才能写好接口文档?十年测试老司机来告诉你

目录 接口文档结构 参数说明 示例 错误码说明 语言基调通俗易懂 及时更新与维护 总结 那么我们该如何写好一份优秀的接口文档呢&#xff1f; 接口文档结构 首先我们要知道文档结构是什么样子的。接口文档应该有清晰明确的结构&#xff0c;以便开发人员能快速定位自己需…...

网站手机端排名怎么做/个人网站制作

文章目录前言一、依赖关系是什么&#xff1f;二、支持的功能总结前言 终于更新一个小的python项目来一起动手学习了&#xff0c;今天想看看Redis源码&#xff0c;可惜太慢太多&#xff0c;思维太乱&#xff0c;于是想到看是否用Python可以分析出这个源码直接的依赖关系。 一、…...

阿里云建站方案/sq网站推广

由于Winsock在被调用时是以动态链接库Winsock.dll的形式实现的&#xff0c;所以在它初始化时应首先调用WSAStartup函数&#xff0c;对Winsock DLL进行初始化&#xff0c;确定被调用的Winsock的版本号&#xff0c;并以此分配必要的资源&#xff1a; int WSAStartup( __in WORD …...

深圳网站制作公司嘉兴/网络营销的主要手段和策略

...

wordpress forbidden/seo搜索优化公司

1 开发工具1.1 独立开发环境PL—>VivadoPS&#xff08;ARM&#xff09;-->SDK&#xff08;Xilinx&#xff09;或者第三方ARM开发工具1.2 集成开发环境SDSoC1.3 总结 独立开发环境大概分为四个步骤&#xff1a;&#xff08;1&#xff09…...

高端网站建设网页设计/搜索引擎优化的要点

&#x1f4d6;本篇内容&#xff1a;leetcode每日一题382. 链表随机节点 链表随机数使用 或 蓄水池抽样 小学抽卡问题 &#x1f4d1; 文章专栏&#xff1a;leetcode每日一题《打卡日常》 &#x1f4c6; 最近更新&#xff1a;2022年1月15日 leetcode每日一题1716. 计算力扣银行…...

研发app大概要多少钱/百度代做seo排名

一、DDoS趋势的一些变化 从今年3月份起&#xff0c;世界上最大的DDoS攻击记录到了1.7 Tbps&#xff0c;是一个普通家庭带宽出口的数十万倍&#xff0c;几乎可以横扫互联网&#xff0c;作为一个生存了20年之久的古老攻击形式&#xff0c;我们看到了今年来DDoS攻击量成指数级攀升…...