【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号进程)领养,这个子进程就叫做孤儿进程。这个子进程变成孤儿进程的同时也变成了一个后台进程。

相关文章
|
1月前
|
并行计算 Linux
Linux内核中的线程和进程实现详解
了解进程和线程如何工作,可以帮助我们更好地编写程序,充分利用多核CPU,实现并行计算,提高系统的响应速度和计算效能。记住,适当平衡进程和线程的使用,既要拥有独立空间的'兄弟',也需要在'家庭'中分享和并行的成员。对于这个世界,现在,你应该有一个全新的认识。
146 67
|
2月前
|
存储 Linux 调度
【Linux】进程概念和进程状态
本文详细介绍了Linux系统中进程的核心概念与管理机制。从进程的定义出发,阐述了其作为操作系统资源管理的基本单位的重要性,并深入解析了task_struct结构体的内容及其在进程管理中的作用。同时,文章讲解了进程的基本操作(如获取PID、查看进程信息等)、父进程与子进程的关系(重点分析fork函数)、以及进程的三种主要状态(运行、阻塞、挂起)。此外,还探讨了Linux特有的进程状态表示和孤儿进程的处理方式。通过学习这些内容,读者可以更好地理解Linux进程的运行原理并优化系统性能。
74 4
|
2月前
|
Linux
Linux:守护进程(进程组、会话和守护进程)
守护进程在 Linux 系统中扮演着重要角色,通过后台执行关键任务和服务,确保系统的稳定运行。理解进程组和会话的概念,是正确创建和管理守护进程的基础。使用现代的 `systemd` 或传统的 `init.d` 方法,可以有效地管理守护进程,提升系统的可靠性和可维护性。希望本文能帮助读者深入理解并掌握 Linux 守护进程的相关知识。
83 7
|
2月前
|
Linux Shell
Linux 进程前台后台切换与作业控制
进程前台/后台切换及作业控制简介: 在 Shell 中,启动的程序默认为前台进程,会占用终端直到执行完毕。例如,执行 `./shella.sh` 时,终端会被占用。为避免不便,可将命令放到后台运行,如 `./shella.sh &`,此时终端命令行立即返回,可继续输入其他命令。 常用作业控制命令: - `fg %1`:将后台作业切换到前台。 - `Ctrl + Z`:暂停前台作业并放到后台。 - `bg %1`:让暂停的后台作业继续执行。 - `kill %1`:终止后台作业。 优先级调整:
118 5
|
2月前
|
Linux 应用服务中间件 nginx
Linux 进程管理基础
Linux 进程是操作系统中运行程序的实例,彼此隔离以确保安全性和稳定性。常用命令查看和管理进程:`ps` 显示当前终端会话相关进程;`ps aux` 和 `ps -ef` 显示所有进程信息;`ps -u username` 查看特定用户进程;`ps -e | grep <进程名>` 查找特定进程;`ps -p <PID>` 查看指定 PID 的进程详情。终止进程可用 `kill <PID>` 或 `pkill <进程名>`,强制终止加 `-9` 选项。
50 3
|
12月前
|
Linux 调度
【Linux】详解进程状态之僵尸进程——孤儿进程
【Linux】详解进程状态之僵尸进程——孤儿进程
207 0
|
12月前
|
Linux 调度
『 Linux 』僵尸进程与孤儿进程
『 Linux 』僵尸进程与孤儿进程
|
Linux 调度
【Linux系统化学习】进程的状态 | 僵尸进程 | 孤儿进程
【Linux系统化学习】进程的状态 | 僵尸进程 | 孤儿进程
【Linux系统化学习】进程的状态 | 僵尸进程 | 孤儿进程
|
Linux Shell 程序员
【Linux】进程状态|僵尸进程|孤儿进程
【Linux】进程状态|僵尸进程|孤儿进程
|
Linux Shell
【Linux取经路】探索进程状态之僵尸进程 | 孤儿进程(二)
【Linux取经路】探索进程状态之僵尸进程 | 孤儿进程(二)
121 1