【Linux系统编程】第十九弹---进程状态(下)

​​​​​​​

  ✨个人主页: 熬夜学编程的小林

💗系列专栏: 【C语言详解】 【数据结构详解】【C++详解】【Linux系统编程】

目录

1、僵尸进程

2、孤儿进程

3、运行状态

4、阻塞状态

5、挂起状态

6、进程切换

总结


1、僵尸进程

上一弹我们讲解了僵尸状态的基本概念,此处我们通过书写代码查看一下僵尸状态。

当一个进程运行完毕、出现问题或者被杀掉以后,它所占用的内存资源和退出状态没有被它的父进程回收,此时这个进程的状态就称为僵尸状态

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>int main()
{pid_t id = fork();if (id == 0){//childint cnt = 5;while (cnt){printf("I am a child,cnt: %d,pid:%d\n", cnt, getpid());sleep(1);cnt--;}}else{//parentwhile (1){printf("I am parent,running always,pid: %d\n", getpid());sleep(1);}}return 0;
}

可以明显看到上图中出现了僵尸状态。

1.僵尸进程与僵尸状态的关系???

僵尸进程是指:一个子进程已经结束运行,但是父进程没有调用wait或waitpid来获取子进程的退出状态信息。

僵尸状态是指:当一个进程运行完毕、出现问题或者被杀掉以后,它所占用的内存资源和退出状态没有被它的父进程回收。

僵尸进程与僵尸状态的关系是,僵尸进程是指处于僵尸状态的进程。这种状态下的进程虽然已经结束执行,但是其进程描述符等资源仍然存在于系统中,直到父进程对其进行善后处理。


2.为什么出现僵尸进程???

僵尸进程是由于,子进程先于父进程退出,但是父进程没有对子进程的资源进行回收(这里的资源指的是内核资源PCB),从而导致子进程的用户资源虽然已被释放,但还占据着PCB资源。

子进程在退出时用户区的资源(子进程的代码和数据)可以自己释放,但是其所占据的内核资源(PCB)需要它的父进程来释放。

注意:如果没有父进程读取,僵尸进程会一直存在(内核数据结构task_struct会一直存在)。(kill -9 不能杀掉进程)

3.为什么父进程不回收子进程PCB??

1.父进程要知道子进程为什么要退出,父进程要获取子进程退出的信息。

2.独立性,父进程只读取子进程的信息,不对信息做修改,依旧保持独立性。

将来子进程被 waitpid(系统调用接口) 等待方式读取了,那么这个子进程会由Z(僵尸)状态变为X(死亡)状态,之后由OS来释放。

僵尸进程危害

进程 = task_struct内核数据结构 + 进程的代码和数据,僵尸进程时会释放进程的代码和数据,但是task_struct内核数据结构还占据一块内存,内存不释放会一直存在,内存不释放会引起内存泄漏问题。

2、孤儿进程

孤儿进程:父进程如果先退出,子进程就会变成孤儿进程。孤儿进程被1号init进程(OS本身)领养,当然要有init进程回收喽。

1. 孤儿进程为什么要被OS领养?

依旧要保证子进程正常被回收。(kill -9能回收)

2.我们已经启动的所有进程,我们怎么从来没有关心过僵尸进程呢?内存泄漏呢?

直接在命令行中启动的进程它的父进程是bash,bash会自动回收新进程的Z(僵尸)。

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>int main()
{int cnt = 5;while (cnt--){printf("I am a process,pid: %d\n", getpid());sleep(1);}
}

3、运行状态

 ★ 操作系统为了合理分配CPU以及各种硬件资源,保证各个进程的正常运行。操作系统会为CPU创建一个进程队列,也为每一个硬件都创建一个等待队列。

★ 而某一个进程处于运行状态本质上就是操作系统将该进程对应的PCB放入CPU的运行队列中,然后再将PCB中维护进程状态的变量修改为相应的值。

★ PCB里面有进程的各种属性值,以及对应的代码的地址。所以CPU从运行队列中找到PCB取出数据后,可以根据数据得到进程的各种属性值和指令,然后执行相应代码。进程处于运行状态并不意味着该进程此时一定正在被运行,只要该进程处于CPU的运行队列中即可。

注意:CPU是处理数据的速度在纳秒级,运算速度非常快,所以只要进程处于CPU的运行队列中,我们就可以认为该进程正在被运行。
 

一个进程一旦持有CPU,会一直运行到这个进程结束吗?

不会。CPU基于时间片进行轮转调度的。(Linux不是这样调度的,这只是OS教材调度方法之一)

让多个进程以切换的方式进行调度,在一个时间段内同时得以推进代码,就叫做并发

每一个CPU都要有一个自己的运行队列,有两个CPU的话,会存在真正意义上的有两个调度队列。任何时刻,都同时有多个进程在真的同时运行,我们叫做并行
 

4、阻塞状态

阻塞状态:相当于S状态,浅度睡眠,D也算。

用一个C语言代码理解阻塞:

#include<stdio.h>
int main()
{int a=0;scanf("%d",&a);printf("a = %d\n",a);return 0;
}

运行该代码,等待键盘资源是否就绪,键盘上面有没有被用户按下的按键,等待则进程没有被调度,也就不会在运行队列中。

阻塞:把进程从运行队列剥离到等待队列。

操作系统如何对硬件进行管理?

本质是对硬件的数据进行管理,因此在操作内核会有对应该硬件属性的结构体。

#define KEY_BOARD 1
#define SCREEN 2
struct device
{int type;int status;//其他属性struct device* next;task_struct* wait_queue;
}

不是只有CPU有自己的运行队列,各种设备也有自己的wait_queue。

★ CPU处理数据的速度极快,是我们计算机中的各种硬件处理数据的万倍,比如:一个磁盘或者一个网卡同时只能为一个进程服务,但是在计算机中需要使用这些硬件资源(磁盘等)的进程会有很多。

★ 如果在硬件为一个进程服务时,有其他运行中的进程也需要使用该硬件资源,操作系统就会将该进程的PCB放入硬件的等待队列中,进程会等待硬件来为自己提供服务。

 ★由于多个进程需要访问某种硬件,进程PCB在硬件等待队列中等待硬件服务自己的状态就被称为阻塞状态。阻塞状态在本质上就是将进程的PCB从CPU的运行队列中,放入硬件的等待队列中,然后将PCB中维护进程状态的变量也会修改为相应的值。当该进程获得对应的硬件资源服务时,再将该进程放回CPU的运行队列中。

注意:并不是只有等待硬件资源的进程才处于阻塞状态,一个进程等待另一个进程就绪、一个进程等待软件资源就绪等也是阻塞状态。
 

5、挂起状态

上面我们学习了阻塞状态,处于阻塞状态的进程由于需要等待某种资源,所以它对应的代码和数据在短期内不会被处理(这里的短期指的是对于操作系统而言)。但它们的数据仍储存在内存中,占用存储空间但是不执行,相当于浪费了内存资源。而如果当前操作系统处于高IO(大量向内存输入和向外部设备输出数据)的情况下,可用的内存空间不足,操作系统就会选择性的将这些处于阻塞状态的进程对应的代码和数据转移到磁盘中(唤出),从而节省出内存空间,如果需要使用到这些代码和数据,则从硬盘中转移到内存(唤入)。

频繁的唤入唤出会导致效率问题。用效率换空间。

这种由于内存空间不足,操作系统将在等待资源的进程对应的代码和数据放到磁盘中以节省内存空间的状态就被称为(阻塞)挂起状态。挂起状态不会移动进程的PCB,只会移动进程对应的代码和数据。

补充:虚拟机挂起是将整个操作系统以及代码和数据移动到硬盘中。

挂起并不是释放进程,因为对应的PCB仍然在硬件的等待队列中,当该进程获得对应的资源服务以后,操作系统仍然可以将该进程对应的代码和数据从磁盘加载到内存中来继续运行,其本质是对内存数据的唤入唤出。
 

6、进程切换

A进程在CPU运行队列中运行的时间片到了之后,A进程会脱离CPU的运行进程;B进程会进入CPU的运行队列中运行,那么比如:A进程在CPU中已经运行到了第50行代码后,时间片到了,退出CPU,当A进程再次进入CPU的时候,是重新开始运行呢?还是接上上回第50行的代码继续运行呢?

CPU里面有一套寄存器,会保留A进程运行的数据,当A进程退出CPU的时候,A进程在CPU中已经运行的数据,将由 task_struct 这个结构体来保存,当A进程再次进入CPU时,数据还会回到寄存器原来的位置,所以A进程会接着第50行继续运行。

进程的切换,最重要的一件事情是:上下文数据的保护和恢复。

CPU内的寄存器:

寄存器本身是硬件,具有数据的存储能力,CPU的寄存器硬件只有一套!!!CPU内部的数据,可以有多套,有几个进程,就有几套和该进程对应的上下文数据。

寄存器 != 寄存器的内容

总结


本篇博客就结束啦,谢谢大家的观看,如果公主少年们有好的建议可以留言喔,谢谢大家啦!

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

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

相关文章

普通人也能创业!轻资产短视频带货项目,引领普通人实现创业梦想

在这个信息爆炸的时代&#xff0c;创业似乎成为了越来越多人的梦想。然而&#xff0c;传统的创业模式 keJ0277 往往伴随着高昂的资金投入和复杂的管理流程&#xff0c;让许多普通人望而却步。然而&#xff0c;现在有一种轻资产短视频带货项目正在悄然兴起&#xff0c;它以其低…

apifox接口调试工具的使用,代替postman

官网链接&#xff1a;Apifox &#xff08;代替postman工具&#xff09; 下载apifox工具 使用步骤 安装本地下载的apifox.exx 登录apifox 接口调用

从“制造”到“智造”:“灯塔”经验助力中国制造业转型升级-转载

作者&#xff1a;Karel Eloot&#xff0c;侯文皓&#xff0c;Francisco Betti&#xff0c;Enno de Boer和Yves Giraud 作为中国实体经济的主体&#xff0c;制造业是推动中国经济发展乃至全球制造业持续增长的重要引擎。站在历史与未来交汇的新起点上&#xff0c;中国制造业将背…

2024.05.14 Diffusion 代码学习笔记

配环境 我个人用的是Geowizard的环境&#xff1a;https://github.com/fuxiao0719/GeoWizard。 出于方便考虑&#xff0c;用的pytorch官方的docker容器&#xff0c;因此python版本&#xff08;3.10&#xff09;和原作者&#xff08;3.9&#xff09;不同&#xff0c;其余都是一…

【极简】docker常用操作

镜像images是静态的 容器container是动态的&#xff0c;是基于镜像的&#xff0c;类似于一个进程。 查看docker images&#xff1a; docker images 或者docker image ls 查看docker container情况&#xff1a;docker ps -a&#xff0c;-a意思是--all 运行一个container: doc…

DCMM(数据管理能力成熟度模型)对企业的价值

随着大数据时代的来临&#xff0c;数据已成为企业发展的重要驱动力。为了有效地管理和利用数据&#xff0c;企业需要建立一套完善的数据管理体系&#xff0c;而DCMM&#xff08;数据管理能力成熟度模型&#xff09;正是这样一个帮助企业构建和优化数据管理能力的框架。 DCMM结构…

LeetCode 235. 二叉搜索树的最近公共祖先

LeetCode 235. 二叉搜索树的最近公共祖先 1、题目 题目链接&#xff1a;235. 二叉搜索树的最近公共祖先 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个结点 p、q&#xff0c;最近公共祖先表…

表的创建与操作表

1. 创建表 创建表有两种方式 : 一种是白手起家自己添&#xff0c;一种是富二代直接继承. 2. 创建方式1 (1). 必须具备条件 CREATE TABLE权限存储空间 (2). 语法格式 CREATE TABLE IF NOT EXISTS 表名(字段1, 数据类型 [约束条件] [默认值],字段2, 数据类型 [约束条件] [默…

C++ 结构体内存对齐

定义了两个结构体 typedef struct Cmd {uint8_t ua;uint8_t ub;uint8_t uc;uint32_t ue; } Cmd_t;typedef struct Cmd_tag {uint8_t value;uint8_t data[1]; // 将 data 定义为指向 Cmd_t 结构体的指针 } tag_t;在实际使用中&#xff0c;看见前人的代码是&#xff0c;new 一块内…

ArcGIS arcpy代码工具——关于标识码的那些事(查找最大标识码、唯一性检查、重排序、空值赋值)

系列文章目录 ArcGIS arcpy代码工具——批量对MXD文件的页面布局设置修改 ArcGIS arcpy代码工具——数据驱动工具批量导出MXD文档并同步导出图片 ArcGIS arcpy代码工具——将要素属性表字段及要素截图插入word模板 ArcGIS arcpy代码工具——定制属性表字段输出表格 ArcGIS arc…

C 深入指针(4)

目录 一、字符指针变量 1 初始化 2 与字符串数组的区别 二、数组指针变量 1 初始化 2 二维数组传参本质 三、函数指针变量 1 初始化 2 用法 四、typedef关键字 五、函数指针数组 一、字符指针变量 1 初始化 //VS2022 x64 #include <stdio.h> int main() {…

供应链投毒预警 | 开源供应链投毒202404月报发布(含投毒案例分析)

概述 悬镜供应链安全情报中心通过持续监测全网主流开源软件仓库&#xff0c;结合程序动静态分析方式对潜在风险的开源组件包进行动态跟踪和捕获&#xff0c;发现大量的开源组件恶意包投毒攻击事件。在2024年4月份&#xff0c;悬镜供应链安全情报中心在NPM官方仓库&#xff08;…

利用远程控制软件FinalShell远程连接虚拟机上的Linux系统(Windows)

一. VMware Workstation 安装CentOS Linux操作系统 传送门&#xff1a;VMware Workstation 安装CentOS Linux操作系统 1.右键打开终端 2.输入ifconfig 找到ens33对应 inet的id&#xff0c;这个就是虚拟机的ip地址图中所示为&#xff1a;192.168.5.128 3.打开finalshell 如…

YOLOv5改进 | Neck | 添加双向特征金字塔BiFPN【小白轻松上手 | 论文必备】

&#x1f680;&#x1f680;&#x1f680;本专栏所有的改进均可成功执行&#x1f680;&#x1f680;&#x1f680; 尽管Ultralytics 推出了最新版本的 YOLOv8 模型。但YOLOv5作为一个anchor base的目标检测的算法&#xff0c;YOLOv5可能比YOLOv8的效果更好。但是针对不同的数据…

抖店商品详情API接口(产品参数|详情图)

抖店商品详情API接口(产品参数|详情图) 参数仅供参考&#xff1a; {"code": 0,"msg": "调用成功","time": "1715763239","data": {"properties": [{"format": [{"message": [{&q…

Linux(九) 信号

目录 一、什么是信号 二、信号的种类 三、信号的产生 3.1 通过终端按键产生信号 Core Dump 核心转储 3.2 调用系统函数向进程发信号 3.3 由软件条件产生信号 3.4 硬件异常产生信号 四、信号的注册 五、信号的注销 六、信号的三种处理方式 七、信号的递达阻塞未决 八…

摸鱼大数据——大数据导论

大数据导论 1、概念 大数据时代: 万物皆数据 ​ 数据概念: 人类的行为及产生的事件的一种记录称之为数据 ​ 数据价值: 对数据的内容进行深入分析&#xff0c;可以更好的帮助了解事和物在现实世界的运行规律 2、大数据诞生 大数据的诞生: 跟随着互联网的发展的,当全球互联…

【面试干货】一个数组的倒序

【面试干货】一个数组的倒序 1、实现思想2、代码实现 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 1、实现思想 创建一个新的数组&#xff0c;然后将原数组的元素按相反的顺序复制到新数组中。 2、代码实现 package csdn;public class…

ssl证书价格一年多少钱?如何申请?

由于行业新规&#xff0c;现在阿里云、腾讯云等几乎所有平台都不再提供一年期免费证书&#xff0c;如果需要一年期证书则需要支付一定的费用。SSL证书的价格根据类型不同几十到几百上千不等。 一年期SSL证书申请通道https://www.joyssl.com/?nid16 一年期SSL证书申请流程&am…

13、24年--信息系统治理——IT审计

1、IT审计基础 1.1 IT审计定义 无重要的考点,自己读课本了解即可。 1.2 IT审计目的 1)IT审计的目的是指通过开展IT审计工作,了解组织IT系统与IT活动的总体状况,对组织是否实现IT目标进行审查和评价,充分识别与评估相关IT风险,提出评价意见及改进建议,促进组织实现IT目…