【Linux初阶】进程状态 | Linux下常见进程状态讲解 进程循环打印方法 ls>makefile指令 makefile$@^特殊符号的应用

news2024/12/28 21:29:31

 🌟hello,各位读者大大们你们好呀🌟

🍭🍭系列专栏:【Linux初阶】

✒️✒️本篇内容:进程状态的概念,进程状态在普遍操作系统层面和Linux层面的理解,Linux常见进程状态,进程状态的两种查看方法,ls>makefile指令,makefile$@^特殊符号的应用方法展示,僵尸进程和孤儿进程的讲解

🚢🚢作者简介:计算机海洋的新进船长一枚,请多多指教( •̀֊•́ ) ̖́-

目录

一、进程状态 

1.普遍操作系统层面理解

(1)运行状态

(2)阻塞状态 

(3)挂起状态

(4)状态合作

2.Linux层面理解

(1)R运行状态(running)

(2)S睡眠状态(sleeping)

(3)D磁盘休眠状态(Disk sleep)

(4)T停止状态(stopped)

(5)t - 被追踪状态 (tracing stop)

(6)X死亡状态(dead)

(7)Z(zombie) - 僵死状态

二、进程状态查看 & makefile特殊符号$@^应用

1.基础进程查看方法 

2.进程循环打印查看方法

3.ls > makefile(重定向)

4.makefile特殊符号$@^应用

三、特殊状态下的进程 - 僵尸进程&孤儿进程

1.僵尸进程

(1)僵尸进程的概念

(2)僵尸进程的危害

2.孤儿进程


一、进程状态 

进程状态有很多,运行、挂起、阻塞、死亡等都属于进程状态。进程那么多状态,实际上都是为了满足不同的运行场景。我们可以从普遍的操作系统层面Linux层面两个层面去理解。在深入学习进程状态的知识前,我们先要了解几个重要的概念。

  1. 一个CPU有一个运行队列
  2. 让进程进入队列,本质:将该进程的task_struct结构体对象(PCB)放到运行队列中,而不是将进程对应的代码放到运行队列中
  3. 进程在runqueue(运行队列)中,就是R,而不是说这个程序在运行,才是运行状态;进程状态是对PCB属性的描述,因此状态的数据也储存在内存中
  4. 不要以为你的进程只占用CPU资源,也有可能它需要占用外设资源,更进一步可能造成资源浪费(当大量进程需要和外设交互,而外设只能执行一个进程的时候)
  5. 所谓进程的不同状态,本质是进程在不同队列中等待某种资源!

1.普遍操作系统层面理解

(1)运行状态

一个CPU有一个运行队列,让进程进入队列,进程在runqueue(运行队列)中,就是R(运行状态),而不是说这个程序在运行,才是运行状态。

注意:进程在运行队列中,本质上是PCB在运行队列中,CPU可以根据PCB找到对应的进程。

 

(2)阻塞状态 

将某个进程从运行队列中剥离下来,放到硬件的等待队列中,进程的状态就变为阻塞状态了。待进程完成与硬件的交互任务或者有需要时,先将进程状态重新变为运行状态,再将进程控制块(PCB)返回运行队列。

 

 

(3)挂起状态

为了更好的利用计算机资源,当内存中存在大量进程的时候,操作系统会将部分不需要立即调度的代码和数据暂时保存在磁盘上。这样,就可以实现内存空间资源的充分利用。

将进程的相关数据,加载或保存到磁盘,此时的进程状态被称为挂起状态待有需要时,会先将进程状态重新改为运行状态,再将进程控制块(PCB)返回运行队列

阻塞 vs 挂起 :阻塞不一定挂起,挂起一定阻塞!因为阻塞不一定会将PCB加载到磁盘,它也可以放到其它硬件的等待队列中,但是加载到磁盘后PCB一定在磁盘的等待队列中。

(4)状态合作

操作系统通过调整进程状态,充分调度计算机软硬件资源,实现计算机的高效运转。例如,当下我们的计算机可以同时运行多个程序,就是CPU配合操作系统在1s内将多个进程运行多次(CPU计算速度非常快),随时间对不同进程进行重复运行,才得以实现的。


2.Linux层面理解

下面的状态在kernel源代码里定义:

/*
* 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 */
};

(1)R运行状态(running)

  • 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里

(2)S睡眠状态(sleeping)

  • 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断(interruptible sleep))

当运行大型程序或者循环时,进程多处于S状态。这是因为CPU运行很快,但是外设很慢,我们获取显示器信息反馈相比于CPU计算速度相差很大,因此出现了阻塞,在Linux下就是睡眠状态S。睡眠状态是阻塞状态的一种。

(3)D磁盘休眠状态(Disk sleep)

  • 有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO(输入输出)的结束。
  • 休眠状态通常只能在高IO的情况下查看。

浅度睡眠,可以被终止(前台进程)(状态S)

深度睡眠,不可以被终止(后台进程)(状态D)

理解深度睡眠:为了避免存在于内存中的重要进程在计算机高负荷运转时被杀掉或覆盖,所以需要给它们设定一个特殊状态——休眠状态(D),它只能通过进程自己醒来(IO结束或断电),而无法被OS杀掉,从而有效的保护了重要进程和相关数据。

(4)T停止状态(stopped)

  • 可以通过发送 SIGSTOP 信号给进程来停止进程。停止下来的进程会处于停止状态(T),这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。
  •  可以通过 kill 命令改变进程状态

进程暂停下来的状态就是停止状态,暂停运行、继续运行指令如下

kill -19 3552(进程id)    #暂停运行
kill -9 3552(进程id)    #继续运行

通过Ctrl+C能终止的进程称为前台进程(状态符号后带有+号),不能被Ctrl+C终止的进程称为后台进程(状态符号后没有带有+号)

当一个进程从暂停状态再回到运行状态,它将转变为后台进程 

(5)t - 被追踪状态 (tracing stop)

  • 在此状态下,代表该进程正在被调试追踪

(6)X死亡状态(dead)

  • 这个状态只是一个返回状态,你不会在任务列表里看到这个状态
kill -18 3552(进程id)    #杀死进程

(7)Z(zombie) - 僵死状态

  • 僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程没有读取到子进程退出的返回代码时,就会产生僵死状态,而在这种状态下的进程我们称他们为僵尸进程


二、进程状态查看 & makefile特殊符号$@^应用

1.基础进程查看方法 

ps axj | head -1 && ps axj | grep myproc  或
ps axj | head -1 && ps axj | grep 4974(进程id)
  • ps axj - 查看系统所有进程
  • head -1(数字1) - 打印标题
  • grep ‘myproc’ - 对除文件myproc外进行行过滤

进程在被调度运行的时候,进程就具有对应的动态属性 

2.进程循环打印查看方法

while :; do ps axj | head -1 && ps axj | grep myproc | grep -v grep; sleep 1; done;
# while :; do -------- 死循环显示
# grep -v grep ------- 过滤grep进程(进程查看命令grep运行时,grep也算一个进程)
# sleep 1; ------ 每隔一秒循环一次
# done; --------结束

3.ls > makefile(重定向)

创建makefile文件,将当前 ls目录下的文件名加载到 makefile中

[ldx@VM-12-11-centos ~]$ ls > makefile

4.makefile特殊符号$@^应用

在makefile文件中可以使用下面这种写法

  • $@ 代表 myprocess:myprocess.c 中冒号左边的部分(目标/生成文件)
  • $^   代表 myprocess:myprocess.c 中冒号右边的部分(依赖文件)
myprocess:myprocess.c
gcc - o $@ $^ -g
.PHONY:clean
clean :
rm - f myprocess


三、特殊状态下的进程 - 僵尸进程&孤儿进程

1.僵尸进程

(1)僵尸进程的概念

要学习僵尸进程,首先我们要知道进程被创造是为了完成某种任务的,在进程完成任务的过程中,我们需要知道它完成任务的情况。在一个进程结束的时候,我们是否也需要知道它情况呢?答案是,需要的。

实际上,在进程退出的时候,是不能立即释放该进程对应的资源的,需要保存一段时间,让父进程或者OS数据读取和回收。

结合前文我们对僵死状态的学习,我们知道了僵尸进程的来源,那就是子进程退出时,父进程没有接收到子进程退出的返回代码,此时子进程就会处于无法回收的状态,此时的子进程就称为僵尸进程。

  • 僵尸进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。
  • 所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态。

代码演示

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
    pid_t id = fork();
    if (id == 0)
    {
        //child
        while (1) {
            printf("I am child process, pid: %d, ppid: %d\n", getpid(), getppid());
            sleep(1);
            exit(1);
        }
    }
    else
    {
        //parent
        while (1)
        {
            printf("I am parent proceass, pid: %d, ppid: %d\n", getpid(), getppid());
            sleep(1);
        }
    }

    return 0;
}

在我们把上述代码运行起来后,打开另一个服务器窗口进行进程循环打印,我们可以看到一段时间后出现了下面这种情况

  • 因为子进程已经结束,而父进程还在运行,进程 ./myprocess 的子进程状态改变为 Z+,父进程状态不变
  • defunct - 死亡
  • 停止进程 ./myprocess后,父子进程都被终止,僵尸进程消失,资源被操作系统回收

(2)僵尸进程的危害

  1. 进程的退出状态必须被维持下去,因为他要告诉关心它的进程(父进程),你交给我的任务,我办的怎么样了。可父进程如果一直不读取,那子进程就会一直处于Z状态。
  2. 维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说,Z状态一直不退出,PCB就一直都要维护。
  3. 那一个父进程创建了很多子进程,就是不回收,是不是就会造成内存资源的浪费?是的!因为数据结构对象本身就要占用内存,想想C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空间!
  4. 会造成内存泄漏?是的!

2.孤儿进程

  1. 在程序运行过程中,存在父进程先退出,子进程后退出的情况。
  2. 父进程先退出,子进程就称之为“孤儿进程”
  3. 最终子进程会被1号进程(操作系统)领养。(1号进程的名称和操作系统的版本有关,常见的名称有init、system等,不过它们本质为操作系统)
  4. 为什么要这么干呢?如果不领养,那么子进程退出的时候,对应的僵尸进程就无法回收了。
  5. 如果前台进程的子进程,成为了孤儿进程,会自动变为后台进程。

代码演示

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
    pid_t id = fork();
    if (id == 0)
    {
        //child
        while (1) {
            printf("I am child process, pid: %d, ppid: %d\n", getpid(), getppid());
            sleep(1);
        }
    }
    else
    {
        //parent
        while (1)
        {
            printf("I am parent proceass, pid: %d, ppid: %d\n", getpid(), getppid());
            sleep(1);
        }
    }
    return 0;
}

  

在我们把上述代码运行起来后,再使用指令将父进程杀掉,我们可以看到出现了下面这种情况

kill -9 9703

子进程被1号进程领养,即该子进程的父进程 id 变为1。再通过查看指令,我们可以得知,1号进程就是我们的操作系统


 🌹🌹Linux进程状态的知识大概就讲到这里啦,博主后续会继续更新更多Linux操作系统的相关知识,干货满满,如果觉得博主写的还不错的话,希望各位小伙伴不要吝啬手中的三连哦!你们的支持是博主坚持创作的动力!💪💪 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/465357.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【论文阅读】轻量化网络MobileNet-V1

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、摘要二、MobileNet-V1核心点介绍&#xff1a;普通卷积和深度可分离卷积三、两个超参数四。后续实验 前言 今天重温一下轻量化经典论文MobileNet-V1&#x…

拿下车载激光雷达份额「第一」,图达通寻求「变阵」

在2022年的量产元年之后&#xff0c;激光雷达正尝试进入真正大规模量产周期。在此之前&#xff0c;有一些关键问题需要解决&#xff0c;其中包括&#xff1a;其一&#xff0c;帮助主机厂将激光雷达真正用起来&#xff0c;发挥价值&#xff1b;其二&#xff0c;丰富产品品类&…

【C语言】文件的相关操作(一文10分钟彻底弄懂)

前言&#xff1a; 欢迎各位童学来到本文&#xff0c;本文将主要通过一个实战案例&#xff08;奥运会奖牌&#xff09;来帮助各位小伙伴们熟悉并掌握文件的相关操作&#xff0c;相信经过一个实战案例的小项目后大家对文件的相关操作应该都能够轻车熟路了&#xff01; &#x1f…

仔细观察Binder和mmap;分析Android进程间通信

前言 Binder是Android系统中的一种IPC&#xff08;进程间通信&#xff09;机制&#xff0c;它使得不同进程中的组件能够互相交互和通信。在Binder中&#xff0c;一个进程中的客户端和另一个进程中的服务器之间通常通过Binder驱动程序进行通信。这种通信方式能够提供安全性和效…

材料写作技巧:关于“新”排比句40例

1.是新时代新征程举旗定向的“宣言书”&#xff0c;是新时代新征程伟大思想的“领航标”&#xff0c;是新时代新征程推进中国式现代化的“动员令”&#xff0c;是新时代新征程自我革命的“冲锋号”。 2.胸怀家国&#xff0c;树立远大理想&#xff0c;奋力担当新时代青年使命&a…

真题详解(数据流图平衡)-软件设计(五十九)

真题详解&#xff08;磁盘&#xff09;-软件设计&#xff08;五十八)https://blog.csdn.net/ke1ying/article/details/130376289 如何保证数据流图平衡&#xff1f; 父图中输入流输出流的名称和数目必须和子图的相同。 父图中一条输入输出流可以对应子图几条输入输出流&…

MATLAB实现OCR自动阅卷,识别答题卡进行成绩统计

利用MATLAB进行答题卡识别编程设计&#xff0c;最主要的是实现了将答题卡中被填涂的答案提取出来&#xff0c;然后与标准的答案进行比对。通过相关的算法&#xff0c;算出考生填涂正确的题数&#xff0c;并统计计算后的得分。 每种答题卡都有很明显的助识别标记&#xff0c;像…

LeetCode - 494 目标和

目录 题目来源 题目描述 示例 提示 题目解析 算法源码 题目来源 494. 目标和 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给你一个整数数组 nums 和一个整数 target 。 向数组中的每个整数前添加 或 - &#xff0c;然后串联起所有整数&#xff0c;可以构造一个…

MathType如何成功插入到word

有时候我们重装mathtype的时候&#xff0c;我们的word里嵌入的mathtype没有了&#xff0c;因此我们如何让它重新出来呢&#xff1f;下面我们来看看。 1、我们打开word&#xff0c;点击“选项”&#xff0c;点击“加载项”找到如图所示的路径内容&#xff08;根据自己电脑的实际…

IDA 知识汇总

工具使用-IDA从入门到理解 - 简书作者ID:leishi-yanmu IDA对于各位师傅应该无需简介了,如果写的不对的地方,还望师傅们多多包涵。讲解的时候会涉及到笔者在学习和使用时候的理解。 启动界面介绍: ...https://www.jianshu.com/p/190805574432[原创]【iOS逆向与安全】利用IDA…

实现网页顶部线性加载进度条

插件一&#xff1a;NProgress.js 下载链接&#xff1a;https://github.com/rstacruz/nprogress 插件二&#xff1a;MProgress.js 下载链接&#xff1a;https://github.com/lightningtgc/mprogress.js/ 这两个插件都是实现网页加载进度条&#xff0c;并且默认方法有四个&…

kitti数据集预处理

kitti数据集预处理 0.引言0.1.calib0.2.oxts(gps/imu)0.3.velodyne0.4.image_2/30.5.kitti-step/panoptics0.6.label 1.create_kitti_depth_maps2.create_kitti_masks3.create_kitti_metadata4.extract_dino_features5.run_pca 0.引言 官网参考链接1参考链接2 注&#xff1a;…

Linux基础指令(1)

Linux的基础指令 对于Linux的学习&#xff0c;先从指令开始学&#xff0c;我们先了解操作系统的一般性概念&#xff0c;然后对于Linux的一些基本的指令进行学习&#xff0c;最后我们发现Linux实际上是一个多叉树的目录结构 文章目录 Linux的基础指令操作系统操作系统是什么&am…

数据可视化开源工具软件

数据可视化工具用于通过图形、图表、表格、地图和其他详细的视觉对象来表示信息。 它们通常将数据呈现和分析结合起来&#xff0c;以帮助专业人员在数据驱动领域(如工程、数据科学和业务分析)做出更明智的决策。 选择正确的数据可视化工具将帮助您减少数据错误&#xff0c;并…

基于本地知识构建简易的chatPDF

Langchain chatglm-6b 文章目录 Langchain chatglm-6b前言一、实验记录1.1 环境配置1.2 代码理解1.3 补充内容 二、总结 前言 介绍&#xff1a;一种利用 ChatGLM-6B langchain 实现的基于本地知识的 ChatGLM 应用 Github: https://github.com/imClumsyPanda/langchain-Chat…

阳光开朗孔乙己,会否奔向大泽乡

前言 &#x1f525;学历对职业关系到底有什么影响呢&#xff1f;&#x1f525;学历给我们带来了优势吗&#xff1f;&#x1f525;到底是什么造成了"孔乙己的长衫"&#xff1f; 孔乙己是中国清代作家鲁迅创作的一篇短篇小说&#xff0c;发表于1919年。这部作品被认为是…

Blender 建模案例一(2)

目录 1. 烛台基座1.1 导入图片1.2 从立方体取一个顶点1.3 用点描边1.4 旋转1.5 实体化修改器1.6 删除内部正面1.7 封盖1.8 平滑着色1.9 表面细分修改器1.10 环切线&#xff08;卡线&#xff09; 1. 烛台基座 1.1 导入图片 1.2 从立方体取一个顶点 中间顶点尽量也X轴平行 1.…

FPGA入门系列5--运算符号

文章简介 本系列文章主要针对FPGA初学者编写&#xff0c;包括FPGA的模块书写、基础语法、状态机、RAM、UART、SPI、VGA、以及功能验证等。将每一个知识点作为一个章节进行讲解&#xff0c;旨在更快速的提升初学者在FPGA开发方面的能力&#xff0c;每一个章节中都有针对性的代码…

( 栈和队列) 739. 每日温度 ——【Leetcode每日一题】

❓739. 每日温度 难度&#xff1a;中等 给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 answer[i] 是指对于第 i 天&#xff0c;下一个更高温度出现在几天后。如果气温在这之后都不会升高&#xff0c;请在该位置…

32k*16 薪,3年自动化测试历经3轮面试成功拿下华为Offer....

前言 转眼过去&#xff0c;距离读书的时候已经这么久了吗&#xff1f;&#xff0c;从18年5月本科毕业入职了一家小公司&#xff0c;到现在快4年了&#xff0c;前段时间社招想着找一个新的工作&#xff0c;前前后后花了一个多月的时间复习以及面试&#xff0c;前几天拿到了华为…