[Linux]进程状态

[Linux]进程状态

文章目录

  • [Linux]进程状态
    • 进程状态的概念
    • 阻塞状态
    • 挂起状态
    • Linux下的进程状态
    • 孤儿进程

进程状态的概念

了解进程状态前,首先要知道一个正在运行的进程不是无时无刻都在CPU上进行运算的,而是在操作系统的管理下,和其他正在运行的进程轮流循环使用CPU,而操作系统管理进程是否需要放到CPU上进行计算,所依据的就是进程状态。

阻塞状态

阻塞状态是进程因为等待某种资源就绪,而导致的一种不推进的状态。

阻塞状态从主观上给人的感觉就是进程“卡”住了,比如进程在下载某一个软件过程中,网络断了,进程下载软件的过程就会"卡"住,进程需要等待网络这种资源就绪,才能继续推进。因此进程处于阻塞状态时,一定是在等待某种资源。进程进入阻塞状态是想要通过等待的方式,等具体的资源被别人使用完后,给自身使用。

由于操作系统要管理各种各样的硬件,因此操作系统需要用某种结构的描述硬件,然后为了方便管理要将这些结构组织起来,描述这些硬件时,会有一个描述信息就是等待队列,这个队列会记录正在等待当前硬件资源的进程的PCB,操作系统就是通过这样的大致原理实现的让进程进入阻塞状态:

image-20230804144704352

挂起状态

挂起状态是进程等待某种资源就绪时,操作系统系统将进程在内存中的代码和数据释放的状态。

挂起状态下进程的PCB还在硬件的等待队列上,操作系统认为进程等待的资源需要很长时间才会准备就绪时,就会释放进程在内存中的代码和数据,让多出来的内存空间用于做其他的事情,提高内存的利用率,当进程等待的资源准备就绪后,操作系统就会把进程的代码和数据再加载到内存中,将进程启动起来。

Linux下的进程状态

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下的进程会在task_struct设置一个变量来记录进程状态。

R状态

R状态就是运行状态,说明进程的task_struct在操作系统中的运行状态等待队列之中,在操作系统轮循执行处于运行状态的进程的代码的过程中,被执行。

注意: 运行状态的进程不代表一直都在CPU上执行,而是和其他处于运行状态的进程一样,轮循的被执行。

为了验证R状态,编写如下代码:

#include <stdio.h>int main()
{while(1){}return 0;
}

在Linux系统下运行程序并查看进程状态:

image-20230823170847439

由于这段代码的执行不需要任何资源,不会进入阻塞状态,因此会一直保持运行状态。

S状态

S状态是可中断休眠状态,可中断休眠状态是Linux系统中阻塞状态的一种。

为了验证S状态,编写如下代码:

#include <stdio.h>int main()
{while(1){printf("hello world\n");}return 0;
}

在Linux系统下运行程序并查看进程状态:

image-20230823171246424

在这段代码中虽然程序是一个死循环操作,但是由于循环结构的代码运行很快,而将数据打印到屏幕上很慢,因此造成了程序运行时,大部分的时候都是在等待打印屏幕的资源,因此查询状态时大部分时间查询到的都是S状态。另外可中断休眠状态下的进程可以选择输入ctrl+z终止进程。

D状态

D状态是不可中断休眠状态,不可中断休眠状态是Linux系统中阻塞状态的一种。

D状态是在进程将数据从内存传输到磁盘时,磁盘的压力过大,导致传输数据的速度很慢,进程必须等待数据传输完成处于休眠状态,为了避免操作系统将这个处于休眠状态的进程杀死,因此将进程设置成不可中断休眠状态。D状态不是一种常见的状态,如果进程处于D状态一般说明计算机磁盘压力过大。

T状态

T状态是暂停状态,暂停状态下进程不再继续运行。

为了验证T状态,编写如下代码:

#include <stdio.h>
#include <unistd.h>int main()
{int i = 1;while(1){printf("hello world %d\n", i);i++;sleep(1); //Linux系统提供的休眠函数,头文件是unistd.h}return 0;
}

在Linux系统下运行程序使用kill -19 进程id暂停进程并查看进程状态:

image-20230823184608894

输入kill -18 进程id可以重启进程:

image-20230823185051979

补充: Linux下进程状态后面的+的含义是这是一个前台进程:

image-20230823185204139

进程状态中没有+的是后台进程:

image-20230823185408461

在Linux下前台进程运行时,bash是失效的,而在后台进程运行时bash是可用的,另外后台进程可以使用kill -9 进程id来关闭。

t状态

t状态是追踪式暂停状态,是T状态的一种特例。

为了验证t状态,可以借用gdb工具,使用gdb开启调试一个程序:

image-20230823190655655

Z状态

Z状态被称作僵尸状态,僵尸状态下进程已经完全停止了,但是保留了进程的task_struct和部分数据。进程进入僵尸状态是为了了解进程的运行结果是否出现问题,因为保留的数据中包含退出码等信息,而退出码是用于判断进程运行结果是否出现问题的数据。进程终止后都会进入僵尸状态等待父进程的回收处理。

为了验证T状态,编写如下代码:

#include <stdio.h>
#include <unistd.h>int main()
{pid_t id = fork();if (id == 0){//子进程while(1){printf("我是子进程,我的pid:%d,我的ppid:%d\n", getpid(), getppid());sleep(1);}}else if (id > 0){while(1){printf("我是父进程,我的pid:%d,我的ppid:%d\n", getpid(), getppid());sleep(1);}}return 0;
}

在Linux系统下运行程序使用kill -9 进程id杀死子进程并查看进程状态:

image-20230823200716754

僵尸进程的危害: 由于僵尸状态下进程的task_struct和数据得到保留,因此会占用内存空间,如果创建多个子进程不回收就会造成大量的空间被占用,造成严重的内存泄露问题。

X状态

X状态被称作死亡状态,死亡状态下进程完成停止了,并且操作系统会很快将进程的task_struct和代码和数据回收释放。

孤儿进程

孤儿进程是在进程运行时,父进程停止,父进程转为操作系统(1号进程),被操作系统管理的进程。

为了验证孤儿进程,编写如下代码:

#include <stdio.h>
#include <unistd.h>int main()
{pid_t id = fork();if (id == 0){//子进程while(1){printf("我是子进程,我的pid:%d, 我的ppid:%d\n", getpid(), getppid());sleep(1);}}else if (id > 0){//父进程int cnt = 5;while(1){printf("我是父进程,我的pid:%d, 我的ppid:%d\n", getpid(), getppid());sleep(1);if (--cnt == 0) break;}}return 0;
}

为了方便编译,编写如下makefile文件:

myproc:myproc.cgcc -o $@ $^
.PHONY:clean
clean:rm -f myproc

准备好代码和makefile文件后编译得到程序,然后运行程序,并使用while :; do ps axj | head -1 && ps axj | grep myproc | grep -v grep; sleep 1; done指令来每隔一秒查询一次进程状态:

image-20230824134857086

进程myproc中的父进程的父进程是bash,它停止后进入僵尸状态后,bash作为其父进程会进行回收操作,因此无法看到其僵尸状态,进程myproc中的子进程仍在进行,但是原有父进程停止了,需要有新的父进程来回收它,否则会造成其停止后,僵尸状态无法回收的情况。

变成孤儿进程后,就变成了后台进程,可以选择使用killall 进程名指令杀死同一进程名的所有进程。

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

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

相关文章

分享好用的翻译软件

网易有道翻译→网易有道翻译

(6)(6.3) 自动任务中的相机控制

文章目录 前言 6.3.1 概述 6.3.2 自动任务类型 6.3.3 创建合成图像 前言 本文介绍 ArduPilot 的相机和云台命令&#xff0c;并说明如何在 Mission Planner 中使用这些命令来定义相机勘测任务。这些说明假定已经连接并配置了相机触发器和云台(camera trigger and gimbal ha…

网络安全等级保护2.0

等保介绍 信息系统运维安全管理规定&#xff08;范文&#xff09;| 资料 等保测评是为了符合国家法律发挥的需求&#xff0c;而不是安全认证&#xff08;ISO&#xff09; 一般情况没有高危安全风险一般可以通过&#xff0c;但若发现高位安全风险则一票否决 二级两年一次 三…

无公网IP内网穿透使用vscode配置SSH远程ubuntu随时随地开发写代码

文章目录 前言1、安装OpenSSH2、vscode配置ssh3. 局域网测试连接远程服务器4. 公网远程连接4.1 ubuntu安装cpolar内网穿透4.2 创建隧道映射4.3 测试公网远程连接 5. 配置固定TCP端口地址5.1 保留一个固定TCP端口地址5.2 配置固定TCP端口地址5.3 测试固定公网地址远程 前言 远程…

FreeSWITCH 1.10.10 简单图形化界面2 - 并发性能测试

FreeSWITCH 1.10.10 简单图形化界面2 - 并发性能测试 0. 界面预览1. 测试工具批量创建baresip配置文件批量注册baresipSIP终端 2. 测试方法fsapi呼叫脚本 3 服务器环境CPU 配置内存配置 4 语音并发测试结果&#xff08;1&#xff09;1000分机&#xff0c;创建账号后&#xff0c…

Vue脚手架安装(全网最详细)

目录 1、环境准备 1.1 安装node 1.1.2 判断你是否安装成功 1.1.3 在命令提示符中查看node版本 1.2 安装webpack 1.3 安装vue-cli3.x以上 2、创建工程 2.1 创建 2.2 选择 2.2.1 选择自定义设置&#xff1a; 2.2.2 选择Vue版本&#xff1a; 2.2.3 是否使用历史模式选择…

Lio-sam代码分析(1)-基本框架说明

Lio-sam代码分析&#xff08;1&#xff09;-基本框架说明 概述LIO-SAM整体框架imageProjecion图像映射节点FeatureExtraction 特征提取mapOptmization 图优化节点imuPreintergration IMU预积分 概述 LIO-SAM是Tixiao又一次的升级,主要是加入了IMU进行了紧耦合(而gps和loop可有…

解密长短时记忆网络(LSTM):从理论到PyTorch实战演示

目录 1. LSTM的背景人工神经网络的进化循环神经网络&#xff08;RNN&#xff09;的局限性LSTM的提出背景 2. LSTM的基础理论2.1 LSTM的数学原理遗忘门&#xff08;Forget Gate&#xff09;输入门&#xff08;Input Gate&#xff09;记忆单元&#xff08;Cell State&#xff09;…

基于微信小程序的物流管理系统3txar

在此基础上&#xff0c;结合现有物流管理体系的特点&#xff0c;运用新技术&#xff0c;构建了以 springboot为基础的物流信息化管理体系。首先&#xff0c;以需求为依据&#xff0c;对目前传统物流管理基础业务进行了较为详尽的了解和分析。根据需求分析结果进行了系统的设计&…

19万字智慧城市总体规划与设计方案WORD

导读&#xff1a;原文《19万字智慧城市总体规划与设计方案WORD》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 感知基础设施 感知基础设施架构由感知范围、感知手…

Centos7 安装Docker 详细多图版

配置要求 Docker CE&#xff08;社区免费版&#xff09; 支持 64 位版本 CentOS 7&#xff0c;并且要求内核版本不低于 3.10&#xff0c; CentOS 7 满足最低内核的要求&#xff0c;所以我们在CentOS 7安装Docker。 一、Centos安装Docker 1.1 卸载&#xff08;可选&#xff0…

springboot+docker实现微服务的小例子

【任务】&#xff1a; 创建一个服务A&#xff1a;service_hello 创建一个服务B&#xff1a;service_name service_name负责提供一个api接口返回一个name字符串。 service_hello负责从这个接口获取name字符串&#xff0c;然后进行一个字符串拼接&#xff0c;在后面加一个hello&…