【Linux】进程状态(R运行状态、S睡眠状态、D磁盘休眠状态、T停止状态、X死亡状态)

        

目录

01.运行状态

02.睡眠状态

03.磁盘睡眠状态

04.停止状态

05.死亡状态


        进程的状态会随着操作系统的调度和外部事件的发生而不断地发生转换。例如,一个新创建的进程经过初始化后会进入就绪态,等待被调度执行;当调度器分配处理器资源给进程时,进程进入运行态;如果进程发起了I/O操作,它可能会进入阻塞态等待I/O完成;当I/O完成后,它重新回到就绪态等待再次执行;当进程执行完毕或被终止时,进程进入终止态

        进程状态的合理转换是操作系统正常运行的基础,也是实现多任务并发的关键。下面我们来理解进程的各个运行状态。以下是总览:

  • R运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列 里。
  • S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠 。
  • D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的 进程通常会等待IO的结束。
  • T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可 以通过发送 SIGCONT 信号让进程继续运行。
  • X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态。

01.运行状态

在理解进程状态时,首先要理解下面几个概念:

操作系统调度机制

操作系统负责计算机软硬件资源管理,其主要任务之一是有效地调度多个进程,以便它们能够并发执行在多任务处理中,有多个进程需要与处理器进行交互,但处理器一次只能执行一个进程的指令,因此操作系统需要有一种机制来管理这些进程的执行,以便它们可以在处理器上轮流运行。运行队列就是这样的一种机制。

运行队列

运行队列是操作系统内核中的一个数据结构,用于存储处于就绪态的进程,即哪些已经准备好执行但尚未获得处理器的进程。其通常是一个先进先出队列,其中进程按照加入就绪态的顺序排列。

时间片

每个进程在处理器上的执行时间是多少呢,此时就要引入一个时间片的概念,时间片代表了每个进程在处理器上连续执行的时间。通过将处理器的执行时间分割成小的时间片段,操作系统可以轮流地为每个就绪态的进程分配处理器时间,从而实现多任务并发执行。

注意:在一般情况下,只有处于就绪态的进程才会被放入运行队列并被分配时间片,当进程编程阻塞态时就会被移出运行队列,不过在一些复杂的情况下有可能会被移到某种阻塞队列中等待资源可用。

当进程由运行队列被放到处理器中时,就有了运行态,处理器为其分配时间片,使其能够在规定的时间内执行指令,处理任务。这种状态下的进程可能会在一段时间后被操作系统挂起,以便为其他进程腾出空间。

进程挂起

进程挂起是指将一个正在运行的进程暂时停止执行,使其暂时不占用处理器资源。这种操作可以通过操作系统的特定调用或信号来实现。当一个进程被挂起时,它的执行状态被保存,以便稍后可以恢复执行。在进程被挂起期间,操作系统可能会将处理器分配给其他就绪态的进程,以实现多任务处理。

挂起进程与阻塞进程不同,因为阻塞进程通常是由于等待某些事件而无法继续执行,而挂起进程是由操作系统或用户显式地将其暂停执行。

02.睡眠状态

当进程处于睡眠状态时,它暂时不需要处理器资源,因为它在等待某些事件的发生。睡眠状态的进程可能在等待I/O操作完成、等待信号量、等待定时器等。一旦等待的事件发生,进程就会被唤醒并切换到就绪态。

下面用代码来演示进程从睡眠状态到就绪状态再到运行状态的过程:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main() {pid_t pid = fork(); // 创建子进程if (pid < 0) {// 创建进程失败perror("fork failed");exit(1);} else if (pid == 0) {// 子进程代码printf("子进程睡着了...\n");sleep(5); // 子进程睡眠5秒printf("子进程醒了!\n");exit(0); // 子进程结束} else {// 父进程代码printf("父进程在等子进程结束...\n");wait(NULL); // 父进程等待子进程结束printf("父进程开始运行了...\n");}return 0;
}

在这个示例中:

  1. 父进程调用 fork() 创建子进程。
  2. 子进程进入睡眠状态,睡眠5秒钟。
  3. 在子进程睡眠期间,它处于睡眠状态,不占用处理器资源。
  4. 当5秒钟过去后,子进程被唤醒,结束睡眠状态,并转换为就绪态。
  5. 父进程调用 wait() 等待子进程结束。
  6. 子进程结束后,父进程继续执行。

03.磁盘睡眠状态

进程处于磁盘睡眠状态时,它正在等待磁盘I/O操作完成。这种状态通常在进程需要大量磁盘读写操作时出现,例如,文件系统操作、数据库操作等。

磁盘睡眠状态和睡眠状态都表示进程暂时无法执行,但磁盘睡眠状态特指等待磁盘 I/O 操作完成的情况,而睡眠状态则是一个更广泛的概念,包括等待各种不同类型事件发生的情况。

04.停止状态

T (stopped)和t (tracing stop)统称为停止状态。

T (stopped): 进程被停止时,它暂时停止执行指令,但仍然保留在系统中。这种状态通常由调试器暂停、SIGSTOP信号等触发。停止状态的进程可以被重新启动,继续执行。

t (tracing stop): 进程被追踪暂停时,通常是为了调试目的。在这种状态下,调试器可以查看进程的内部状态、寄存器值等,以帮助排查程序问题。

下面是一个简单的示例,说明进程被停止的情况:

假设有一个简单的 C 程序,如下所示:

#include<stdio.h>
#include<unistd.h>int main()
{while(1){printf("我是一个进程...\n");sleep(1);}return 0;
}

在这个程序中,进程将不断打印消息,模拟持续执行。

然后,可以使用gdb调试器在程序运行过程中停止该进程:

$ gcc -g -o proc proc.c
$ gdb proc
(gdb) run

然后,在另一个终端中,找到该进程的进程 ID(PID)并发送 SIGSTOP 信号来停止它:

kill -STOP 66414

先前的终端显示以下信息表示进程被停止: 

尽管进程暂时停止执行指令,但它仍存在于系统中,可以通过调试器重新启动或进行其他操作。

05.死亡状态

 死亡状态通常指的是进程已经终止执行并退出,但其相关的进程描述信息仍然保留在系统中,直到其父进程对其进行清理。

进程终止

进程终止是指进程执行完毕或者由于某种错误导致其异常终止。在进程终止时,它的执行环境、资源和内存空间会被操作系统回收和释放。

僵尸进程

当一个进程终止后,其父进程需要调用 wait()waitpid() 等系统调用来获取子进程的退出状态,否则子进程的进程描述信息会被保留在系统中,形成僵尸进程。僵尸进程不再执行任何操作,但其相关的进程描述信息(如进程 ID、退出状态等)仍然存在于系统的进程表中。

清理僵尸进程

父进程应当定期调用 wait()waitpid() 等系统调用来清理僵尸进程,从而释放相关的进程描述信息,防止系统资源的浪费。如果父进程长时间不清理僵尸进程,那么系统可能会耗尽进程表项,导致无法创建新的进程。

处理僵尸进程

父进程可以通过 wait()waitpid() 等系统调用来处理僵尸进程,获取子进程的退出状态并释放相关的资源。这样做可以确保系统中不会出现大量僵尸进程,保持系统资源的有效利用。

以上就是进程状态的有关知识了,欢迎评论区留言,觉得俺的博客对你有帮助的,可以点赞关注支持一波喔~😉

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot学习笔记一、SpringBoot应用初创建以及应用

一、创建SpringBoot的两种方式 1.Spring Initializr方式创建 &#xff08;1&#xff09;第一步在IDEA中选择 File-->NEW-->Project &#xff0c;选择 Spring Initializr &#xff0c;指定Maven坐标、包名、指定 JDK 版本 1.8 &#xff0c;然后点击Next 。如下图&#x…

亚信安慧AntDB解析:数据库技术的新里程碑

AntDB简化了开发运维&#xff0c;更提高了数据库的易用性。AntDB是一种创新的数据库管理系统&#xff0c;其设计理念旨在让用户能够更便捷地进行数据库操作&#xff0c;减少繁琐的配置和管理工作&#xff0c;提升工作效率。 通过AntDB&#xff0c;用户可以快速部署和管理数据库…

leetCode刷题 20. 有效的括号

目录 题目&#xff1a; 1. 思路 2. 解题方法 3. 复杂度 4. Code 题目&#xff1a; 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型…

USART发送单字节数据原理及程序实现

硬件接线&#xff1a; 显示屏的SCA接在B11&#xff0c;SCL接在B10&#xff0c;串口的RX连接A9&#xff0c;TX连接A10。 新建Serial.c和Serial.h文件 在Serial.c文件中&#xff0c;实现初始化函数&#xff0c;等需要的函数&#xff0c;首先对串口进行初始化&#xff0c;只需要…

Teamcenter 快速获取所有激活状态用户的方法

问题描述&#xff1a; License数量有限&#xff0c;需要分析Teamcenter 中所有激活状态下的用户&#xff0c;对其进行删减。如何快速获取Teamcenter 中所有激活状态用户呢&#xff1f; 解决方法&#xff1a; Teamcenter Query Builder提供了强大的自定义搜索功能。 新建查询…

Jenkins--在Linux上使用Docker安装

一、Jenkins 简介 Jenkins是一个流行的开源自动化服务器&#xff0c;用于持续集成和持续交付&#xff08;CI/CD&#xff09;。Jenkins的核心功能主要包括以下几点&#xff1a; 持续集成&#xff1a;Jenkins可以监控版本控制系统&#xff08;如Git、SVN&#xff09;中的代码变…

TCP重传机制详解——02SACK

文章目录 TCP重传机制详解——02 SACKSACK是什么&#xff1f;为什么要有SACK&#xff1f;实际场景抓包具体显示信息流程 实战抓包讲解SACK关闭场景下&#xff0c;三次重复ACK后会快速重传SACK打开但是不携带SACK块信息场景下&#xff0c;三次重复ACK也不会快速重传SACK打开并且…

Docker搭建LNMP环境实战(04):安装VMwareTools共享文件夹

1、加载VMware Tools安装盘 在VMware客户端&#xff0c;点击主菜单&#xff1a; 图1 启动VMware Tools安装 再点击下面的菜单&#xff1a; 图2 打开设置界面 出现下面的界面&#xff0c;虚拟DVD加载的是linux.iso 图3 查看VMware Tools的DVD虚拟安装映像文件 将DVD加载到CentO…

C++ 控制语句(一)

一 顺序结构 程序的基本结构有三种&#xff1a; 顺序结构、分支结构、循环结构 大量的实际问题需要通过各种控制流程来解决。 1.1 顺序结构 1.2 简单语句和复合语句 二 循环 2.1 for循环 语句流程图 注意&#xff1a;使用for语句的灵活性 三 while语句 四 do while语句

SpringCloud详解(持续更新)

springcloud定义 springcloud搭建 Eureka&#xff08;注册发现&#xff09; Eureka主页信息 Eureka服务注册中心&#xff08;Eureka Server&#xff09; 搭建 失效剔除&#xff08;配置&#xff09; Eureka服务提供方&#xff08;Eureka Client&#xff09; 搭建 Eureka服务消…

基于DWT(离散小波变换)的图像水印算法,Matlab实现

博主简介&#xff1a; 专注、专一于Matlab图像处理学习、交流&#xff0c;matlab图像代码代做/项目合作可以联系&#xff08;QQ:3249726188&#xff09; 个人主页&#xff1a;Matlab_ImagePro-CSDN博客 原则&#xff1a;代码均由本人编写完成&#xff0c;非中介&#xff0c;提供…

Avalonia笔记2 -数据集合类控件

学习笔记&#xff1a; 1. DataGrid 笔记1中已经记录&#xff1b; 2. ItemsControl 属性&#xff1a; ItemsSource&#xff1a;数据源 ItemsControl.ItemTemplate&#xff1a;单项数据模板&#xff0c;内部使用<DataTemplate> 示例&#xff1a; <ItemsContr…