进程状态以及两种特殊进程

news2024/12/23 0:21:03

目录

  • 进程状态
    • 1 具体状态
    • 2 进程状态的意义
    • 3 进程状态实例
      • 3.1 R&S&T认识
      • 3.2 认识Z & 僵尸进程 & 孤儿进程
        • 僵尸进程
        • 孤儿进程

进程状态

为了弄明白正在运行的进程是什么意思,我们需要知道进程的不同状态。一个进程可以有几个状态(在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 */
};

1 具体状态

1.1 运行状态

  • R 运行状态(running):

    • 并不意味着进程一定在运行中,它表明进程要么是在运行中,要么在运行队列里。

    • 一个进程处于运行状态,实质上是这个进程已经被放入运行队列run_quene当中,随时可被CPU进行调度。(等待CPU)

1.2 睡眠状态

当我们完成某种任务时,任务条件不具备,需要进程进行某种等待,此时这种状态称为 S 或 D。一个外设可能被多个进程等待,此时这个队列叫做等待队列wait_queue(等待外设)。当“等待成功”,进程将被设为R状态,进入运行队列run_quene

  • S 睡眠状态(sleeping):意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠interruptible sleep),可能会被杀掉。 (浅度睡眠

  • D 磁盘休眠状态(Disk sleep):有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束,进程如果处于D状态,不可被杀掉。(深度睡眠

所谓的进程,在运行的时候,有可能因为运行需要,可能会在不同的队列里。

因此,在同一个队列里,所处的状态不一定是一样的。

我们把,从运行状态的task_struct(run_queue),放到等待队列中,就叫做挂起等待(阻塞)

从等待队列,放到运行队列,被CPU调度就叫做唤醒进程!

1.3 停止状态

  • T 停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。

  • t (tracing stop):追踪导致的暂停状态(断点之类)。

1.4 死亡状态&僵尸状态

  • X 死亡状态(dead):这个状态只是一个返回状态,不会在任务列表里看到这个状态。
    • 回收进程资源=进程相关的内核数据结构+相关代码和数据
  • Z 僵尸状态(zombie):进入僵死状态,辨别“死亡原因”,即进程退出的信息,系统将此信息保存在task_struct里,供系统或父进程进行读取。

进程的状态信息存在task_struct(PCB)里。

image-20230425224057518

2 进程状态的意义

方便OS快速判断进程,完成特定的功能,比如调度,本质是一种分类。

3 进程状态实例

3.1 R&S&T认识

代码myproc.cc

#include<iostream>
#include<unistd.h>
int main(){
    while(true){
        std::cout << "hello world !" << std::endl;
    }
    return 0;
}

运行并查看进程状态,为S+
image-20230426131457300
查看可执行的kill,并停止目标进程
image-20230426131726464
查看停止后进程状态,为T
image-20230426132236164
使进程继续运行,kill -18,并查看进程状态,此时我们发现,进程状态为S,并且使用ctrl+c不能停止进程了
image-20230426133014414
这是因为此时进程在后台运行,此时需用kill -9(SIGKILL)杀掉进程
image-20230426133320500

  • 前台运行:直接使用 ./myproc
  • 后台运行:使用 ./myproc &,后台进程,可以在当前页面继续执行其他命令

3.2 认识Z & 僵尸进程 & 孤儿进程

僵尸进程

僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程没有读取到子进程退出的返回代码时就会产生僵死(尸)进程。

僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。

所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态

首先通过下面这个例子认识一下Z进程。

myproc.cc

#include <iostream>
#include <unistd.h>
int main(){
    
  pid_t id = fork();
    
  if(id == 0){
     //child
    while(true){
      std::cout << "I am child, running !" << std::endl;
      sleep(2);
    }
  }
  else{
    //parent
    std::cout << "father do nothing!\n" << std::endl;
    sleep(50);
  }
  return 0;
}
  • 运行./myproc,使用while :; do ps axj | head -1 && ps ajx | grep myproc | grep -v grep; sleep 1; echo "############################################"; done查看当前进程状态

    image-20230426195030189

  • 使用kill -9杀掉子进程

    image-20230426195207641

    image-20230426195242091

可以看到,因为无回收的操作,子进程成为僵尸进程

父进程如果一直不读取,那子进程就一直处于Z状态,Z状态一直不退出,PCB一直都要维护。

长时间不回收,占用系统资源,而C中定义一个结构体变量,是要在内存的某个位置进行开辟空间,此时僵尸进程的存在也有可能造成内存泄漏

如果父进程先”死“,那么子进程会如何,谁来回收它呢?

孤儿进程

父进程如果提前退出,那么子进程后退出,进入Z之后,那该如何处理呢?父进程先退出,子进程就称之为“孤儿进程”

孤儿进程被1号init进程领养,由init进程回收。

myproc.cc

#include <iostream>
#include <unistd.h>
int main(){
    
  pid_t id = fork();
    
  if(id == 0){
     //child
    while(true){
      std::cout << "I am child, running !" << std::endl;
      sleep(2);
    }
  }
  else{
    //parent
    std::cout << "father do nothing!\n" << std::endl;
    sleep(10);
    exit(1);
  }
  return 0;
}
  • 开始运行。

    image-20230426200257763

  • 10秒后,父进程结束,子进程依然在。并且进程状态由S+变为S,ppid变为1,称此时的进程为孤儿进程,而”领养孤儿进程“的1号进程通常为操作系统

    image-20230426201059595

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

==、equals区别 | java学习笔记

做一些java基础知识的记录&#x1f4d5; java基本类型&#xff1a;byte short int long float double char boolean&#xff08;指向具体的数值&#xff09; java引用类型&#xff1a;类 接口 数组等。指向的不是具体的数值&#xff0c;而是指向了对象的地址。 用于判断基本类…

JavaWeb|在IDEA中创建基于Maven的Web项目| Servlet依赖|这一篇就够了(超详细)

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;老茶icon &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开兴好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;计…

【c语言】详解c语言#预处理期过程 | 宏定义前言

c语言系列专栏&#xff1a; c语言之路重点知识整合 创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; 给大家跳段街舞感谢支持…

微信小程序php+python+nodejs+vue大学生心理健康测试职位推荐系统

心理测试开发使系统能够更加方便学生捷&#xff0c;同时也促使心理测试变的更加系统化、有序化。系统界面较友好&#xff0c;易于操作。具体在系统设计上&#xff0c;客户端使用微信开发者&#xff0c;后台也使用php技术在动态页面上进行了设计&#xff0c;Mysql数据库&#xf…

算法 DAY44 动态规划6 完全背包 518. 零钱兑换 II 377. 组合总和 Ⅳ

完全背包 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品都有无限个&#xff08;也就是可以放入背包多次&#xff09;&#xff0c;求解将哪些物品装入背包里物品价值总和最大。 完全背包和01背包问题唯一不同…

Java每日一练(20230427)

目录 1. 螺旋矩阵 2. LRU 缓存机制 3. 解数独 &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 螺旋矩阵 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#…

Leetcode——495. 提莫攻击

&#x1f4af;&#x1f4af;欢迎来到的热爱编程的小K的Leetcode的刷题专栏 文章目录 1、题目2、题目分析3、题解代码 1、题目 题目链接&#xff1a;Leetcode——495. 提莫攻击 在《英雄联盟》的世界中&#xff0c;有一个叫 “提莫” 的英雄。他的攻击可以让敌方英雄艾希&…

国民技术N32G430开发笔记(1)-macos开发环境搭建

macos开发环境搭建 1、安装arm-none-eabi- 工具链 brew tap ArmMbed/homebrew-formulae brew install arm-none-eabi-gcc如果没有安装brew&#xff0c;请先安装brew。 2、安装vscode 3、安装pyocd a、python官网下载最新版的python b、pip3 install -U pyocd 我的开发板为N3…

Hadoop 1:Apache Hadoop、HDFS

Hadoop核心组件 Hadoop HDFS&#xff08;分布式文件存储系统&#xff09;&#xff1a;解决海量数据存储 Hadoop YARN&#xff08;集群资源管理和任务调度框架&#xff09;&#xff1a;解决资源任务调度 Hadoop MapReduce&#xff08;分布式计算框架&#xff09;&#xff1a;解决…

MyBatis的代理开发方式、动态sql语句和typeHandlers和plugins标签实战

文章目录 Mybatis的Dao层实现传统开发方式编写UserDao接口编写UserDaoImpl实现mapper文件测试传统方式 代理开发方式代理开发方式介绍编写UserMapper接口测试代理方式 MyBatis映射文件深入动态sql语句动态sql语句概述动态 SQL 之<if>动态 SQL 之<foreach>SQL片段抽…

信号处理的本质是什么?

信号处理的宗旨是“将信号中蕴涵的信息变得显然”&#xff0c;从数学角度分析, 信号即是某个物理量x的函数f(x), 信号所蕴含的信息需要通过此类函数予以揭示. 自然地可将f(x)投影到其所在空间中的一组基函数上, 由投影系数或加权系数来构成函数f(x)在变换域上的表示。在一定条件…

Nginx基本配置

文章目录 准备环境安装NginxNginx配置初始配置信息配置详解1. 全局块2. events 块3. http 块3.1 http 全局块3.2 server 块3.2.1 全局 server 块3.2.2 location 块 启动Nginx 参考资料 本教程讲述Nginx的基本配置和操作。首先需要安装 Nginx&#xff0c;关关于具体的安装方式&a…

输入网址url到网页显示,期间发生了什么?

当我们在浏览器输入一个网址后&#xff0c;知道网页显示在我们眼前&#xff0c;这一期间是如何发生的&#xff0c;接下来就将详细介绍在这期间发生的过程及使用的协议栈 1、浏览器解析URL并生产HTTP请求消息 URL是我们输入的网址信息&#xff0c;比如 https://www.taobao.com …

JavaScript 知识总结下篇(更新版)

91.实现一个 promise 参考链接&#xff1a;实现一个完美符合Promise/A规范的Promise Issue #4 forthealllight/blog GitHub function myPromise(constructor) {let self this;self.status "pending" // 定义状态改变前的初始状态self.value undefined;// 定义状…

c++调用java方法详解

当我们使用 Java程序调用C程序时&#xff0c;我们可以使用JAVA_HOME类来访问 Java虚拟机中的类&#xff0c;并使用其提供的方法来调用 Java方法。 使用JAVA_HOME类调用 Java方法时&#xff0c;可以在 JVM中直接操作 Java虚拟机。这个方法称为“直接访问”&#xff08;Direct Ac…

华为交换机配置telnet登录图文教程

一、配置交换机管理vlan和地址&#xff0c;配置交换机接口 1.关闭多余的信息提示&#xff1a; [Huawei]undo in en Info: Information center is disabled. [Huawei] 2.交换机配置 在工作中通过Telnet方式登录交换机进行设备登录管理能更加便利&#xff0c;不需要到机房里…

7.参数校验

在controller和service进行前端传参校验&#xff0c;保证存到数据库的数据是正确的 1.引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency>这里无需…

科技云报道:生成式AI大模型,或将撼动云服务市场格局

科技云报道原创。 随着ChatGPT、GPT-4、BARD等生成式AI大模型的爆火&#xff0c;云服务商围绕生成式AI的竞争日趋激烈。 微软将Azure的企业级功能与OpenAI的生成式AI模型功能相结合&#xff0c;发布了Azure OpenAI服务&#xff1b; 紧随其后&#xff0c;谷歌开放了AI大模型Pa…

File类知识梳理(包含输入输出流的使用)

前言 学习的思维导图 目录 1. File类是什么? 2. 关于文件系统的操作 3. 关于文件内容的操作 3.1 文本文件 3.2 二进制文件 4. 案例实现练习 5.拓展:try with resources 操作 1. File类是什么? ● 概念 它的实例化对象是对硬盘上文件或目录的抽象表示.文件存储在硬盘…

【Java实战篇】Day15.在线教育网课平台--持续集成

文章目录 一、Devops1、什么是Devops2、什么是CI/CD3、Devops方案参考 二、人工部署1、项目打jar包2、生成镜像、创建容器 三、自动化部署1、代码提交到git2、修改pom.xml文件3、前端部署 一、Devops 1、什么是Devops 一个软件的生命周期包括&#xff1a;需求分析阶、设计、开…