【Linux】进程排队的理解&&进程状态的表述&&僵尸进程和孤儿进程的理解

简介: 【Linux】进程排队的理解&&进程状态的表述&&僵尸进程和孤儿进程的理解

一、进程排队的理解

      进程不是一直运行的,进程可能会在等待某种软硬件资源。即使把进程加载到CPU中,也不是一直会运行的。而进程排队,一定是在等待某种软硬件资源(可以是CPU,键盘,磁盘,网卡等等设备......),排队时是进程的PCB在排队在这里就需要引入一个概念:一个PCB可以被链入多种数据结构中在之前的博客中也说过,PCB其实就是描述进程的一个很大的结构体,在这个结构体中,包含有很多其他的结构体比如我定义一个node结构体

struct node
{
    struct node* prev;
    struct node* next;
}

       该结构体可以指向它的前一个节点,也可以指向它的后一个节点。也就是说,进程排队不是我们简单地理解的是进程的PCB去排队,而是PCB内部的各个结构体通过prev指针和next指针连接起各个进程去排队,从而可以让进程在不同的队列中进行排队。如下图所示。也就是说,当我们要把某一个task_struct结构体链入某一个队列中时,我们不必把它从全局双链表中移除,可以直接链入队列中。

       通过task_struct结构体内部listnode相对于task_struct结构体首地址的地址偏移量,也可以找到task_struct结构体开始的地址,进而找到task_struct结构体。

二、进程状态的表述--运行、阻塞、挂起

运行状态

       所谓的状态,本质就是一个整形变量,是在task_struct中的一个整形变量。状态决定了你的后续动作Linux中可能存在多个进程都要根据它的状态执行后续动作。一个CPU都会维护一个运行队列,当一个进程的PCB被链入到CPU的运行队列中时,我们就称这个进程的状态为运行状态。也就是说,并不是当进程在CPU上运行的时候它才是运行状态,只要进程的PCB被链入到CPU的运行队列中,我们就可以成进程处于运行状态了。运行状态表示进程已经随时准备好接受CPU的调度了。

阻塞状态

       在操作系统层面上,为了管理好底层的硬件,其实操作系统也是把硬件都描述成一个一个的结构体,其中在硬件的结构体中,就有像CPU的运行队列一样的等待队列,当一个进程比如执行到scanf函数必须等待键盘资源时,操作系统就会将该进程的PCB从CPU的运行队列中移除,将表示进程状态的整形变量设置为block,再将该进程的PCB链入到键盘结构体的等待队列中。该进程就开始等待键盘资源了,这个状态我们就称之为阻塞状态。当键盘读到了用户输入的数据,操作系统再将该进程的PCB从键盘的等待队列中移除,链入到CPU的运行队列中,再改变表示进程状态的整形变量,从而实现了进程状态的切换。上面的例子可以总结为,当我们的进程在等待软硬件资源的时候,资源如果没有就绪,我们的进程PCB只能1、设置进程状态为阻塞状态,2、将自己的PCB链入等待资源的等待队列中。进一步的我们也可以了解到,进程状态的变迁,引起的是进程的PCB会被操作系统链入到不同的队列中

挂起状态

阻塞挂起

前提:计算机资源已经比较吃紧当一个进程想要被CPU调度运行时,它对应的代码和数据势必要加载到内存当中。可是如果这个进程此时正处于阻塞状态且对应的硬件资源一时半会儿不会得到相应,而此时计算机的内存资源又比较吃紧的情况下,操作系统就会将这个进程对应的代码和数据先存放到磁盘对应的swap分区中,让其它比较重要的进程优先占有内存,这个动作就叫做唤出动作。等到计算机资源相对宽裕,硬件资源响应时,再将这个进程对应的代码和数据加载到内存中,这个动作就叫做唤入。一旦该进程的PCB在内存中创建出来了而对应的代码和数据不在内存当中,我们就称这个进程为挂起状态

三、Linux中具体的进程状态

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): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列 里。

S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠/浅度睡眠 (interruptible sleep)),是阻塞状态的一种。

D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态/深度睡眠(uninterruptible sleep):在这个状态的进程通常会等待IO的结束,处于D状态的进程在系统资源吃紧的时候也不会被操作系统杀死,也是阻塞状态的一种。

T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程,也是阻塞状态的一种。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行,进程暂停以后就变成了后台进程。kill -19 进程标识符。kill -18 进程标识符:让这个进程继续运行。

X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态

        上面这一段程序是一段死循环,当我把它运行起来时,我们可以看到:

        当前我这个进程是处于睡眠状态(S状态)的。这是因为我的这个程序中执行了printf函数,printf函数是要访问外设的,要访问外设就不可避免的要等待外设响应。而CPU的运行速度是非常非常快的,也就是说相对CPU而言,该进程大部分时间还是在等待外设的,在等待过程中CPU就将该进程链入到外设的等待队列中,所以该进程查到的状态大部分都是睡眠状态,这里的Linux操作系统具体实现的S状态就是上面操作系统层面上的阻塞状态的一种S后面这个+号表示该进程是前台进程,没有+号表示该进程是后台进程

僵尸状态(Z状态)

       当子进程退出时,父进程就必须去读取子进程退出时的退出状态。如果父进程不读取子进程退出时的退出状态,子进程的PCB就不会被系统释放,子进程就会一直处于僵尸状态。创建子进程是为了让这个子进程给用户完成工作的,子进程完成工作后必须得有结果数据,这些数据都保存在子进程的PCB中。这就是为什么要有僵尸状态的原因,是为了获得子进程的结果数据。如果父进程不读取,那么这个僵尸状态的进程会一直存在,会引起内存泄漏,造成系统资源的浪费

       为什么我们在之前的进程没有见过处于Z状态呢?那是因为以前我们创建的进程的父进程都是bash,bash一瞬间会自动读取子进程的退出状态,不需要我们手动读取。而我们自己创建的子进程需要我们自己读取它的退出状态

四、孤儿进程

       当父进程先于子进程退出,子进程会被操作系统(1号进程)领养,这个子进程就叫做孤儿进程。这个子进程变成孤儿进程的同时也变成了一个后台进程。

相关文章
|
12天前
|
算法 Linux 调度
深入理解Linux操作系统的进程管理
本文旨在探讨Linux操作系统中的进程管理机制,包括进程的创建、执行、调度和终止等环节。通过对Linux内核中相关模块的分析,揭示其高效的进程管理策略,为开发者提供优化程序性能和资源利用率的参考。
36 1
|
7天前
|
SQL 运维 监控
南大通用GBase 8a MPP Cluster Linux端SQL进程监控工具
南大通用GBase 8a MPP Cluster Linux端SQL进程监控工具
|
15天前
|
运维 监控 Linux
Linux操作系统的守护进程与服务管理深度剖析####
本文作为一篇技术性文章,旨在深入探讨Linux操作系统中守护进程与服务管理的机制、工具及实践策略。不同于传统的摘要概述,本文将以“守护进程的生命周期”为核心线索,串联起Linux服务管理的各个方面,从守护进程的定义与特性出发,逐步深入到Systemd的工作原理、服务单元文件编写、服务状态管理以及故障排查技巧,为读者呈现一幅Linux服务管理的全景图。 ####
|
1月前
|
缓存 监控 Linux
linux进程管理万字详解!!!
本文档介绍了Linux系统中进程管理、系统负载监控、内存监控和磁盘监控的基本概念和常用命令。主要内容包括: 1. **进程管理**: - **进程介绍**:程序与进程的关系、进程的生命周期、查看进程号和父进程号的方法。 - **进程监控命令**:`ps`、`pstree`、`pidof`、`top`、`htop`、`lsof`等命令的使用方法和案例。 - **进程管理命令**:控制信号、`kill`、`pkill`、`killall`、前台和后台运行、`screen`、`nohup`等命令的使用方法和案例。
134 4
linux进程管理万字详解!!!
|
20天前
|
缓存 算法 Linux
Linux内核的心脏:深入理解进程调度器
本文探讨了Linux操作系统中至关重要的组成部分——进程调度器。通过分析其工作原理、调度算法以及在不同场景下的表现,揭示它是如何高效管理CPU资源,确保系统响应性和公平性的。本文旨在为读者提供一个清晰的视图,了解在多任务环境下,Linux是如何智能地分配处理器时间给各个进程的。
|
1月前
|
存储 运维 监控
深入Linux基础:文件系统与进程管理详解
深入Linux基础:文件系统与进程管理详解
73 8
|
28天前
|
网络协议 Linux 虚拟化
如何在 Linux 系统中查看进程的详细信息?
如何在 Linux 系统中查看进程的详细信息?
58 1
|
28天前
|
Linux
如何在 Linux 系统中查看进程占用的内存?
如何在 Linux 系统中查看进程占用的内存?
|
1月前
|
算法 Linux 定位技术
Linux内核中的进程调度算法解析####
【10月更文挑战第29天】 本文深入剖析了Linux操作系统的心脏——内核中至关重要的组成部分之一,即进程调度机制。不同于传统的摘要概述,我们将通过一段引人入胜的故事线来揭开进程调度算法的神秘面纱,展现其背后的精妙设计与复杂逻辑,让读者仿佛跟随一位虚拟的“进程侦探”,一步步探索Linux如何高效、公平地管理众多进程,确保系统资源的最优分配与利用。 ####
70 4
|
1月前
|
缓存 负载均衡 算法
Linux内核中的进程调度算法解析####
本文深入探讨了Linux操作系统核心组件之一——进程调度器,着重分析了其采用的CFS(完全公平调度器)算法。不同于传统摘要对研究背景、方法、结果和结论的概述,本文摘要将直接揭示CFS算法的核心优势及其在现代多核处理器环境下如何实现高效、公平的资源分配,同时简要提及该算法如何优化系统响应时间和吞吐量,为读者快速构建对Linux进程调度机制的认知框架。 ####