Linux进程(二)

文章目录

  • 进程(二)
  • Linux的进程状态
    • R (running)运行态
    • S (sleeping)阻塞状态
    • D (disk sleep)深度睡眠
    • T(stopped)状态
    • X(dead)状态
    • Z(zombie)状态
    • 僵尸进程
    • 孤儿进程
  • 进程优先级
    • 更改优先级


进程(二)

前文我们知道了,传统的进程状态为:运行态、阻塞态、挂起,这是教科书上对于操作系统的进程状态描述,但是我们知道,不同的操作系统对于其自身的状态定义和描述是不同的,我们接下来看看Linux中的进程状态是分为哪几种?以及对于优先级的了解。

Linux的进程状态

我们先通过一段Linux的源码来了解一下,Linux有几种进程状态
在这里插入图片描述

/*
* 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 */
};

R (running)运行态

运行态R,在前文已经很详细描述了,其进程的运行的流程,这里简单描述

将准备好运行的进程(实际上PCB即可)放在runqueue队列中,然后通过调度器来选取要将哪一个进程放在cpu上执行,当是时间片结束之后,就将该进程从cpu上拿下来,然后放在runqueue队列的队尾,再次排队,这就是依据时间片的轮转执行进程。

PCB排队,其对应的代码和数据,只有轮到该进程时候,才会调用。

PCB存在,进程就存在,控制一个进程就是控制其PCB

在Linux中R状态又分为两种表示形式,R和R+

区别:

R: 表示的是该进程在后台运行,此时我们只能通过kill -9 PID命令,或者是kill -19 PID来使得该进程结束或停止

R+:表示的是该进程在前台运行,此时我们在进程结束之前无法输入其他指令

选定执行方式:

./proc 默认前台运行proc进程

./proc & 默认后台运行proc进程

在这里插入图片描述

注意:如果程序运行需要I/O时,一般显示S+,表示阻塞状态,虽然先在进程是一直在运行,但是由于CPU处理数据太快,外设输入/输出太慢,导致进程大部分时间都是在等待,所以一般为S+

S (sleeping)阻塞状态

前文也对于阻塞状态做了详细的解释,我们这边也简单描述一下

当进程需要一定的外设输入/输出的时,也就是需要等待资源,这个时候进程并没有准备好被调用,会去找对应的外设,排队,实际上也是PCB排队,当得到资源之后,就会被唤醒,调到runqueue中,由阻塞态转换为运行态。

类型:

S+:表示的是前台,进程处于阻塞状态

S: 表示的是后台,进程处于阻塞状态

注意:此时的阻塞状态,为睡眠,是可以被唤醒的(等资源到位之后就被唤醒,转换成运行态)

在这里插入图片描述

D (disk sleep)深度睡眠

深度睡眠,此时进程阻塞,其对应的代码和数据是可以有可能被挂起的,而且处于当前状态是无法被唤醒,直到状态结束

D状态产生的原因:

在这里插入图片描述

责任判定:

进程:已执行自己的全部任务,且自己只是听从了操作系统的话,结束进程。

操作系统:为了大局着想,此时内存空间资源不足,得释放一些空间,以供其他进程使用,此进程此时比较空闲,我觉得是可以释放的,所以将其杀死,释放该进程,这是执行自己管理软硬件的能力,合理分配资源的职责。

硬盘:我也想反馈信息给进程,但是此时进程已经被杀死,我不知道这个资源到底是作何使用,我也有很多进程是要进行读写的,也需要空间来存储数据,对于该进程存储的数据,我只能按照规定,删除该数据,这是正常操作。

进程、操作系统、硬盘,都认为自己没有责任,而且陈词有理有据。所以应该不是某一部分的责任,应该是设计的问题。

如何解决该设计的问题呢?

我们要实现的目的是,只需要在进程等待磁盘写入完毕的期间,该进程不被任何人给杀掉即可

于是,我们加入的D(disk sleep)状态,磁盘睡眠,也就是深度睡眠状态,规定,处于该状态的进程不允许任何人来打扰,就算是操作系统也不行,在该状态无法被kill

总结:D状态表示进程正在等待某些资源的释放,通常是由于IO操作(如磁盘读写)过程中发生阻塞引起的。

D状态属于阻塞态,为深度睡眠,不可以被唤醒

S和D的区别:

  1. S一定是在等待某一种资源,等待唤醒成为运行态
  2. D可能是在等待某一种资源,也可能是正在被其他资源控制

T(stopped)状态

T状态,就是停止该进程,使得进程暂停运行,我们对于该状态有两种方法能实现

前台:

  1. 对于前台运行的程序,我们可以使用ctrl+z来使得进程停止运行,从而转换成T状态
  2. 对于前台运行的程序,我们可以使用kill -19 PID来使得进程停止运行,从而转换成T状态,通过kill -18 PID 来恢复运行

后台:

  1. 对于后台运行的程序我们只能使用kill -19 和 kill -18的方法

在这里插入图片描述

注意:T和t都是表示进程停止运行,没有太大的差别,所以我们就不讲t状态了

X(dead)状态

X状态,表示的是该进程被杀死,这是一个瞬时状态,我们不好观察到

Z(zombie)状态

Z状态就是僵尸状态,在进程被杀死之前,会先进入Z状态,由父进程得到该进程保留的信息之后,才会交给X状态,从而结束进程

使用kill -9 PID 命令杀死进程,就是先Z然后再X

将进程已经死掉,但是此时没有父进程来进行获取该进程的返回信息,此时操作系统要一直保留该状态,称为Z状态

在这里插入图片描述

总结:

  • 进程退出的时候,如果父进程没有主动回收子进程信息,子进程会一直让自己处于僵尸状态,就需要对于该进程的数据进行维护,进程基本信息存放在PCB中,所以要一直维护PCB进程的相关资源和代码数据信息,尤其的==task_struct结构体不能被释放==
  • 僵尸进程使得内存一直被占用,无法释放(如果父进程一直不回收),那么会导致==内存泄漏==
  • 僵尸状态的原因是,进程退出之前是需要告诉父进程,你交给我的任务我完成了没有,但是父进程一直没有获取子进程的结束信息,所以子进程要一直处于Z状态

那么就有人会讲,为什么./proc,结束后不会看到Z状态呢?

这是因为,被其父进程给接收信息,然后结束进程了,其父进程为bash,会主动在proc进程结束后回收信息,所以我们观察不到Z状态和X状态,然后proc进程就结束了

那么为什么bash不能处理proc的子进程呢?爷爷管孙子不行吗?

任何父进程只对于其子进程负责

僵尸进程

僵尸进程就是该程序运行之后,其子进程没有被父进程回收信息,使得子进程称为僵尸状态。

僵尸进程的代码为:

#include<stdio.h>
#include<unistd.h>int main()
{printf("当前进程的PID为:%d , PPID为: %d\n",getpid(),getppid());pid_t id = fork();if(id==0){//表示这是一个子进程int cnt=5;while(cnt--){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;}

僵尸进程的主要危害就是对于内存一直占用,且没有回收,导致内存泄漏。

因为需要维护该Z状态,就要维护其PCB(存储进程的基础信息),PCB不能被释放,PCB占据不少的空间。从而导致内存泄漏

孤儿进程

孤儿进程顾名思义就是父进程提前退出,而子进程还在运行,子进程为孤儿进程

父进程已经退出,被bash回收处理,子进程如果再想退出,怎么办?

父进程退出后,子进程会被1号进程(init/systemd)领养所以init/systemd来回收子进程

init和systemd是不同版本下1号进程的不同叫法

在这里插入图片描述

孤儿进程被操作系统所领养,1号进程init表示的是操作系统。

为什么不是bash领养呢?

因为任何进程之对于子进程进行回收,所以父进程由bash回收管理,所以孤儿进程不能被bash回收(父亲只管其自己儿子,不会管孙子),这是代码层面不允许,这个时候,操作系统根据其内核来回收

进程优先级

查看进程优先级的方法,ps -al 显示所有当前进程信息

优先级是指对于资源的访问,谁先访问,谁后访问,因为资源是优先的,进程是多个的,注定了,进程之间是竞争关系,所以操作系统必须保证大家良性竞争,确认优先级。

如果我们进程长时间得不到CPU资源,该进程的代码长时间无法得到推荐,就导致了该进程的饥饿问题。

所以优先级的存在,就是为了调度器能够更好的合理利用CPU资源,来公平调度不同的进程。

基本概念

cpu资源分配的先后顺序,就是指进程的优先级

优先级高的进程有优先执行的权利,配置进程优先级对于多任务环境的Linux很有用,可能改善系统性能

可以将进程运行到指定的CPU上,这样不重要的进程放在其他CPU上,可以大大改善系统性能

在这里插入图片描述

主要的信息

  1. UID:代表执行者的身份 (用户ID)
  2. PID:当前进程的进程编号
  3. PPID:当前进程的父进程的编号
  4. PRI:代表这个进程可被执行的优先级,其值越小越早被执行
  5. NI:代表当前进程的nice值

优先级PRI,越小优先级级别越高,NI即nice值,是用来修正优先级数值

PRI(new)=PRI(old)+nice

默认PRI(old)= 80

当nice数值变小,PRI会变小,优先级会变高,便会很快被执行,所以调整进程优先级,实际上就是调整nice数值。

nice的数值范围为-20到19,一共40个级别

注意:实际上进程什么时候被运行,都是根据调度器来控制的,调整优先级,到底什么时候调度不确定,所以只能说是可能会改善系统性能

更改优先级

有多种方式可以更改优先级,也就是说有多种方式能更改nice数值。

以下方式来更改进程优先级

  1. 对于进程使用nice 或者 renice指令进行更改nice数值,进而更改PRI数值。
  2. root用户下,在top(任务资源管理器)中可以按 “ r ” ,之后输入进程PID,然后输入nice数值

注意:

  1. root用户更改的nice范围为[-20,19],非root用户的可更改的nice范围为[0,19]
  2. 非root用户只能将nice越调越高,root用户随意
  3. 非root用户,只能调自己进程的nice值,root用户随意

更改nice数值,如果输入大于或者小于[-20,19]这个范围,取极值

nice指令

用法:对于未执行的进程,在执行前输入nice -n + 指令(进程)

在这里插入图片描述

renice

语法:renice [number] PID

renice是对于已经运行的进程的nice数值进行更改,number表示输入新的nice数值

在这里插入图片描述

top更改nice

top可以显示当前的所有进程运行情况

只有root用户才有权利通过top来更改指定PID的nice数值

非root用户,top更改nice会有以下错误

在这里插入图片描述

优先级对于操作系统很重要,但是操作时候没有那么重要

操作系统是如何根据优先级,开展的调度呢?

基于Linux内核2.6的O(1)调度算法

在这里插入图片描述

主要是,我们通过优先级的加入对于runqueue的结构,再次了解调用进程的过程。

  1. [100,139] 是基于时间片轮转,公平调度的进程,强调公平
  2. [0,99] 是实时进程,强调及时响应,在当代操作系统中一般不会使用,但是某些需要实时进程的是需要的。

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

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

相关文章

MySQL中的事务

系列文章目录 MySQL常见的几种约束 MySQL中的函数 文章目录 系列文章目录前言一、事务及其特征1、事务的概念2、事务的特性&#xff08;1&#xff09;原子性&#xff08;2&#xff09;一致性&#xff08;3&#xff09;隔离性&#xff08;4&#xff09;持久性 二、事务并发问题…

Centos7安装jdk8教程——rpm安装

1. rpm文件下载 下载链接 Java SE 8 Archive Downloads (JDK 8u211 and later) 2.上传到服务器指定路径下并安装 切换到上传目录&#xff0c;然后执行以下命令 rpm -ivh jdk-8u221-linux-x64.rpm3. 设置环境变量并重载配置 # 设置环境变量 vim /etc/profile# 文件末尾添加…

如何维护你的电脑:打造IT人的重要武器

文章目录 方向一&#xff1a;介绍我的电脑方向二&#xff1a;介绍我的日常维护措施1. 定期清理和优化2. 保持良好的上网习惯和安全防护3. 合理安排软件和硬件的使用4. 数据备份和系统还原 方向三&#xff1a;推荐的维护技巧1. 数据分区和多系统安装2. 内部清洁和散热优化3. 安全…

【C++】容器篇(五)—— map和set的基本介绍

序言&#xff1a; 在之前&#xff0c;我们已经对STL中的 序列式容器 进行了相关的学习。本期&#xff0c;我将给大家介绍的则是另外一类容器 —— 关联式容器 &#xff01;&#xff01;&#xff01; 目录 &#xff08;一&#xff09;容器回顾 &#x1f4a8;【顺序容器】 &a…

使用FreeMarker导出word文档(支持导出图片)

今天跟大家分享一下工作中比较实用的导出word 带图片的功能。 对于在idea开发中我们需要引入以下依赖&#xff1a; 2.对于eclipse 开发我们需要进入对应的jar包 这个必须放在lib下&#xff0c;同样也需要在当前项目的环境是加入该依赖 需要在MEAT-INF加入 首先制定word 导出…

git 版本控制与合并

一 git概述&#xff1a; - Git是一种分布式版本控制系统&#xff0c;用于跟踪和管理软件开发项目中的代码变更。 - 它允许多人协同工作&#xff0c;记录代码历史变更&#xff0c;并轻松管理多个项目版本。 **Git的主要特点**包括&#xff1a; 1. **分布式系统**&#xff1a;…

学习笔记-JAVAJVM-JVM的基本结构及概念

申明&#xff1a;文章内容是本人学习极客时间课程所写&#xff0c;文字和图片基本来源于课程资料&#xff0c;在某些地方会插入一点自己的理解&#xff0c;未用于商业用途&#xff0c;侵删。 原资料地址&#xff1a;课程资料 什么是JVM 原文连接&#xff1a; 原文连接 JVM是J…

linuxARM裸机学习笔记(4)----GPIO中断以及定时器中断实验

1.中断向量表 这个表里面存放的都是中断向量&#xff0c;中断服务程序的入口地址或存放中断服务程序的首地址成为中断向量。中断向量表是一系列中断服务程序入口地址组成的表&#xff0c;当某个中断触发的时候会自动跳转到中断向量表对应的中断服务程序的入口。 2.NVIC(内嵌向…

记一次 .NET某医疗器械清洗系统 卡死分析

一&#xff1a;背景 1. 讲故事 前段时间协助训练营里的一位朋友分析了一个程序卡死的问题&#xff0c;回过头来看这个案例比较经典&#xff0c;这篇稍微整理一下供后来者少踩坑吧。 二&#xff1a;WinDbg 分析 1. 为什么会卡死 因为是窗体程序&#xff0c;理所当然就是看主…

【elementui】解决el-select组件失去焦点blur事件每次获取的是上一次选中值的问题

目录 【问题描述】 【问题摘要】 【分析问题】 【完整Test代码】 【封装自定义指令】 ↑↑↑↑↑↑↑↑↑↑↑↑ 不想看解决问题过程的可点击上方【封装自定义指令】目录直接跳转获取结果即可~~~ 【问题描述】 一位朋友遇到这么一个开发场景&#xff1a;在表格里面嵌入el-…

Redis内网主从节点搭建

Redis内网主从节点搭建 1、文件上传2、服务安装3、服务启动4、配置主从复制 1、文件上传 内网环境手动上传gcc-c、redis.tar文件 2、服务安装 # 解压 unzip gcc-c.zip unzip gcc_rpm.zip tar -zxvf redis-6.2.13.tar.gz# 安装 cd gcc_rpm/ rpm -ivh *.rpm --nodeps --force…

以太网ICMP协议(九)

目录 一、概述 二、ICMP消息类型 2.1 ICMP类型0和类型8&#xff1a;Ping功能 2.2 ICMP类型3&#xff1a;目标不可达 2.3 ICMP类型5&#xff1a;重定向 2.4 ICMP类型11&#xff1a;超时 三、报文格式 一、概述 由于IP协议是不可靠的通信协议&#xff0c;需要有其他协议的…