【Linux】认识进程以及进程的状态

目录

认识进程

基本概念

查看进程

父子进程

进程的状态

进程排队

运行状态

阻塞状态

挂起状态

僵尸进程

孤儿进程


认识进程

基本概念

有些教材上会说:正在运行的程序就是进程。这并没有错误,但是太过于笼统。现在我们深入到Linux底层来了解一下什么是进程。

我们想要执行一个程序,就必须要把代码和数据给操作系统。也就是说将其加载到内存中

但是操作系统有很多正在运行的程序,它肯定要把他们都管理起来。怎么做呢?先描述,再组织。也就是说先用结构体把各个进程的基本属性描述出来,然后再用数据结构将这些进程组织起来

这个结构体被称为进程控制块(PCB)。在Linux中PCB命名为task_struct

有了PCB之后,操作系统中一切管理进程的行为,本质都是管理对应的PCB。比如操作系统想要进程排队,只需要让PCB排队就好了。所以我们可以得出一个结论:

进程=内核PCB数据对象+可执行程序

task_ struct常见内容

  • 标示符: 描述本进程的唯一标示符,用来区别其他进程。
  • 状态: 任务状态,退出代码,退出信号等。
  • 优先级: 相对于其他进程的优先级。
  • 程序计数器: 程序中即将被执行的下一条指令的地址。
  • 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
  • 上下文数据: 进程执行时处理器的寄存器中的数据。
  • I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
  • 记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
  • 其他信息

查看进程

查看进程状态:ps ajx 或者 ps aux

但是这样会显示所有的进程,所以我们一般配合着grep使用。比如你要查找一个叫做xxx.exe的进程,你就输入ps ajx | grep xxx.exe即可查找到。

父子进程

在Linux中,每一个进程都有父进程。一切在命令行调用的进程,都是bash的子进程。

上图中PID代表进程的唯一标识符,PPID代表父进程的唯一标识符。我们可以用函数getpid()和函数getppid()去分别获取他们。其包含在<unistd.h>文件中,返回值类型是pid_t 。在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 */
};

在Linux中,PCB内部有一个整型变量来表示进程的状态。比如R状态的位图就是00000000,S状态的位图就是00000001等等。

所以进程状态的本质其实就是一个整型变量,进程状态就是用一个整型来描述的。Linux中会有多个进程都要通过它们的状态来执行后续动作。

_____________________________________________________________________________

进程排队

软硬件资源是有限的,但是我们有很多进程,所以进程需要排队。

进程排队的本质就是PCB在排队。一个PCB内部有许多链表节点,因此可以把一个PCB放入到多个数据结构中进行管理。linux内核的PCB——task_struct是以双向链表的形式链接起来的。想要通过节点找回PCB,可以使用相对地址找回PCB的指针。

获取起始地址的运算:(task_struct*)(&n - (task_struct*)0 ->n)。task_struct中有很多类似于struct listnode的节点,因此它可以链入多个数据结构中。

每个软硬件都有自己的等待队列。当一个进程需要运行,就把它链接到CPU的等待队列中,当一个进程需要网络请求,就把它链接到网卡的等待队列中。对于PCB的状态改变,以及把PCB放到哪一个队列中,都是由操作系统来执行的。

____________________________________________________________________________

运行状态

操作系统给CPU维护了一个等待队列叫做运行队列,运行队列是一个双向循环链表,它容纳了系统中所有可以运行的进程。当task_struct链入到运行队列中就处入运行状态(R状态)。

_____________________________________________________________________________

阻塞状态

堵塞状态就是将task_struct从运行队列中移除再链入到其他等待队列中。

举个例子:你的程序中有一个scanf函数,该程序会从运行队列中移除,将自己的状态改为堵塞,链接到键盘的等待队列中,如果等待成功,就会再将自己从等待队列中移除,链接到运行队列中,将自己的状态改为运行。

_____________________________________________________________________________

S状态

S状态(sleep)休眠状态也可以叫做可中断睡眠状态浅度睡眠状态,属于阻塞状态,其一般处于等待资源的状态。可以用Ctrl+c中断程序。

____________________________________________________________________________

D状态

D状态(disk sleep)也叫做不可中断睡眠状态或者深度睡眠状态,属于阻塞状态。
当Linux过于繁忙的时候,内存中可能会有大量进程,此时操作系统就会选择直接杀掉某些进程,防止崩溃。

D状态,相当于有一个免死金牌,操作系统不会杀掉D状态的进程,而是继续让其等待资源。

_____________________________________________________________________________

T状态

T状态,进程处于暂停状态,属于阻塞状态。

我们可以通过给进程发送信号 kill -19,就是暂停的信号。

如果想要从T状态恢复,可以使用信号 kill -18,即继续进程。

T状态的进程是后台运行的进程,哪怕通过kill -18恢复过来依旧是一个后台进程。

_____________________________________________________________________________

t状态

t状态也是一个暂停状态,属于阻塞状态,但是其是一种被追踪的暂停状态。

比如说使用调试程序的时候,当进程到某个断点处停止了,此时进程就属于t状态。

_____________________________________________________________________________

挂起状态

当内存非常吃紧的时候,操作系统会将一些进程的代码和数据放入到磁盘的一个特定的区域,当缓和时,再将代码和数据放入内存。但注意task_struct不会放入磁盘。这种状态就称为挂起状态。挂起状态是一个特殊的阻塞状态。

____

_________________________________________________________________________

僵尸进程

进程退出后,其代码和数据会被立即释放,但是这个进程的PCB会被保留,因为我们可能需要这个进程的状态信息,此时这个状态就是僵尸状态(Z状态)。所以进程在死亡前一定会进入Z状态。父进程调用wait()或者waitpid()系统调用取得子进程的终止状态,此时进程真正死亡(X状态)。

由父进程创建一个子进程,子进程结束后,如果父进程一直不读取子进程的数据,子进程就会一直被保留,这种进程称之为僵尸进程。

僵尸进程有很大的危害:

  • 僵尸进程的 PID 还占据着,意味着海量的子进程会占据满进程表项,导致后来的进程无法 fock()
  • 僵尸进程的内核栈无法被释放掉(1K 或者 2K大小),导致内存泄漏。

_____________________________________________________________________________

孤儿进程

如果一对父子进程,父进程比子进程先退出,那么子进程的PCB就无法被父进程回收了,对于这种父进程先退出的进程,叫孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue3项目部署在阿里云轻量应用服务器上

文章目录 概要整体部署流程技术细节小结 概要 vue3前端项目部署在阿里云轻量服务器 整体部署流程 首先有一个Vue3前端项目和阿里云应用服务器 确保环境准备 如果是新的服务器&#xff0c;在服务器内运行以下命令更新软件包 sudo apt update && sudo apt upgrade -y …

STM32H7开发笔记(2)——H7外设之多路定时器中断

STM32H7开发笔记&#xff08;2&#xff09;——H7外设之多路定时器中断 文章目录 STM32H7开发笔记&#xff08;2&#xff09;——H7外设之多路定时器中断0.引言1.CubeMX配置2.软件编写 0.引言 本文PC端采用Win11STM32CubeMX4.1.0.0Keil5.24.2的配置&#xff0c;硬件使用STM32H…

Web3 游戏周报(11.17 - 11.23)

回顾上周的区块链游戏概况&#xff0c;查看 Footprint Analytics 与 ABGA 最新发布的数据报告。 【11.17 - 11.23】Web3 游戏行业动态&#xff1a; 加密游戏开发商 Gunzilla Games 发推表示&#xff0c;其已与 Coinbase Ventures 达成合作并获得其投资。 国际足联将与 Mythica…

问题记录-Java后端

问题记录 目录 问题记录1.多数据源使用事务注意事项&#xff1f;2.mybatis执行MySQL的存储过程&#xff1f;3.springBoot加载不到nacos配置中心的配置问题4.服务器产生大量close_wait情况 1.多数据源使用事务注意事项&#xff1f; 问题&#xff1a;在springBoot项目中多表处理数…

微软Ignite 2024:建立一个Agentic世界!

在今年的Microsoft Ignite 2024上&#xff0c;AI Agent无疑成为本次大会的重点&#xff0c;已经有十万家企业通过Copilot Studio创建智能体了。微软更是宣布&#xff1a;企业可以在智能体中&#xff0c;使用Azure目录中1800个LLM中的任何一个模型了&#xff01; 建立一个Agent…

python画图|无坐标轴自由划线操作fig.add_artist(lines.Line2D()函数

【1】引言 新发现了一种自由划线操作函数&#xff0c;和大家共享。 【2】官网教程 点击下述代码&#xff0c;直达官网&#xff1a; https://matplotlib.org/stable/gallery/misc/fig_x.html#sphx-glr-gallery-misc-fig-x-py 官网代码非常简洁&#xff0c;我进行了解读。 …

基于微信小程序的空巢老人健康管理系统

摘 要 随着社会老龄化程度不断加深&#xff0c;空巢老人的健康管理成为一个日益重要的问题。为了更好地关注和管理空巢老人的健康状况&#xff0c;本文利用Spring Boot框架和MySQL数据库&#xff0c;结合微信小程序等技术&#xff0c;设计并实现了一套基于微信小程序的空巢老人…

【JavaEE】Servlet:表白墙

文章目录 一、前端二、前置知识三、代码1、后端2、前端3、总结 四、存入数据库1、引入 mysql 的依赖&#xff0c;mysql 驱动包2、创建数据库数据表3、调整上述后端代码3.1 封装数据库操作&#xff0c;和数据库建立连接3.2 调整后端代码 一、前端 <!DOCTYPE html> <ht…

小程序-使用 iconfont 图标库报错:Failed to load font

官方默认可以忽略此错误&#xff0c;在清除缓存后首次刷新会显示此错误&#xff0c;重新渲染错误消失 解决方法&#xff1a; 在 iconfont 图标库选择项目设置 选中 Base64 保存&#xff0c;重新点击链接 -> 复制代码到项目中 操作步骤&#xff1a;

用CAXA CAD电子图板导入图框、标题栏并导出pdf的方法

1.导入图框&#xff1a; 点击调入图框->出现读入图框文件 一个一个点击&#xff0c;选择合适的图框 然后点击导入 2.导入标题栏&#xff1a; 调入标题栏->出现读入标题栏文件 一个一个点击&#xff0c;选择合适的标题栏&#xff0c;然后点击导入 3.导出pdf&#x…

《Shader入门精要》透明效果

代码以及实例图可以看github &#xff1a;zaizai77/Shader-Learn: 实现一些书里讲到的shader 在实时渲染中要实现透明效果&#xff0c;通常会在渲染模型时控制它的透明通道&#xff08;Alpha Channel&#xff09;​。当开启透明混合后&#xff0c;当一个物体被渲染到屏幕上时&…

加速科技精彩亮相中国国际半导体博览会IC China 2024

11月18日—20日&#xff0c;第二十一届中国国际半导体博览会&#xff08;IC China 2024&#xff09;在北京国家会议中心顺利举办&#xff0c;加速科技携重磅产品及全系测试解决方案精彩亮相&#xff0c;加速科技创始人兼董事长邬刚受邀在先进封装创新发展论坛与半导体产业前沿与…

【JavaEE初阶 — 多线程】线程池

目录 1. 线程池的原理 1.1 为什么要有线程池 1.2 线程池的构造方法 1.3 线程池的核心参数 1.4 TimeUnit 1.5 工作队列的类型 1.6 工厂设计模式 1.6.1 工厂模式概念 1.6.2 使用工厂模式的好处 1.6.3 使用工厂模式的典型案例 1.6.4 Thread…

JSON 性能测试 - WastJson 性能也很快

WAST 是一个高性能 Java 工具集库包&#xff0c;包括 JSON、YAML、CSV、HttpClient、JDBC 和 EL 引擎. WastJson 无论是小中大文本各种数据类型等性能都没有明显的短板&#xff0c;除了推广外可以说是六边形战士&#xff0c;更多测试参考 wast-jmh-test: wast性能测试 (并非所…

数据库-基础理论

文章目录 前言一、ORM框架二、ACID原则三、事务Transaction四、N1问题五、Normalization三范式六、FMEA方法论&#xff08;Failure Mode and Effects Analysis&#xff09;七、Profiling和PerformanceSchema查询分析 前言 基础理论 ORM框架、ACID原则、事务Transaction、N1问…

AI赋能电商:构建高效、智能化的新零售生态

随着人工智能&#xff08;AI&#xff09;技术的不断进步&#xff0c;其在电商领域的应用日益广泛&#xff0c;从购物推荐到供应链管理&#xff0c;再到商品定价&#xff0c;AI正在全面改变传统电商的运营模式&#xff0c;并推动行业向智能化和精细化方向发展。本文将探讨如何利…

[极客大挑战 2019]BabySQL--详细解析

信息搜集 进入界面&#xff1a; 输入用户名为admin&#xff0c;密码随便输一个&#xff1a; 发现是GET传参&#xff0c;有username和password两个传参点。 我们测试一下password点位能不能注入&#xff1a; 单引号闭合报错&#xff0c;根据报错信息&#xff0c;我们可以判断…

计算机网络socket编程(2)_UDP网络编程实现网络字典

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 计算机网络socket编程(2)_UDP网络编程实现网络字典 收录于专栏【计算机网络】 本专栏旨在分享学习计算机网络的一点学习笔记&#xff0c;欢迎大家在评论区交流讨…

GitLab|应用部署

创建docker-compose.yaml文件 输入docker-compose配置 version: 3.8 services:gitlab:image: gitlab/gitlab-ce:15.11.2-ce.0restart: alwayscontainer_name: gitlab-ceprivileged: truehostname: 192.168.44.235environment:TZ: Asia/ShanghaiGITLAB_OMNIBUS_CONFIG: |exter…

虚拟苹果系统MacOS中新建自定义C++Dylib并用C++测试程序测试

前言 苹果系统中Dylib的建立和使用是一个非常基础的功能。本博客使用苹果虚拟机MacOS Ventura 13.6.7&#xff0c;XCode15.2&#xff0c;来复现这个过程。供参考。 1、Dylib框架的建立 2、增加一个函数 注意&#xff0c;向导自动生成的Helloworld函数中嵌套了一个函数Helloworl…