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] 是实时进程,强调及时响应,在当代操作系统中一般不会使用,但是某些需要实时进程的是需要的。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构 二叉树(C语言实现)

绪论 雄关漫道真如铁&#xff0c;而今迈步从头越。 本章将开始学习二叉树&#xff08;全文共一万两千字&#xff09;&#xff0c;二叉树相较于前面的数据结构来说难度会有许多的攀升&#xff0c;但只要跟着本篇博客深入的学习也可以基本的掌握基础二叉树。 话不多说安全带系好&…

关于 Ubuntu 长按 shift 无效, 按 Esc 直接进入 grub 改密码的解决方法

本次长按shift没有反应&#xff0c;直接进入了系统界面&#xff0c;所以改用长按Esc键&#xff0c;步骤如下&#xff1a; 1. 长按esc&#xff0c;进入grub>提示 2.输入grub>normal &#xff0c;回车 3.上一步回车后&#xff0c;继续敲击Esc &#xff0c;出现grub界面 …

HCIP---OSPF的优化

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 一.汇总&#xff1a; 目的&#xff1a;减少骨干区域的LSA的更新量 作用&#xff1a;OSPF的…

可缝合神经网络

文章目录 Stitchable Neural Networks摘要本文方法实验结果 Stitchable Neural Networks 摘要 包含大量强大的预训练模型族(如ResNet/DeiT)的model zoo已经达到了前所未有的范围&#xff0c;这对深度学习的成功有重要贡献。由于每个模型族都由具有不同尺度的预训练模型(例如&…

Linux 匿名页的生命周期

目录 匿名页的生成 匿名页生成时的状态 do_anonymous_page缺页中断源码 从匿名页加入Inactive lru引出 一个非常重要内核patch 匿名页何时回收 本文以Linux5.9源码讲述 匿名页的生成 用户空间malloc/mmap(非映射文件时&#xff09;来分配内存&#xff0c;在内核空间发生…

Docker实战-关于Docker镜像的相关操作(二)

导语   之前的分享中&#xff0c;我们介绍了关于Docker镜像的查询操作相关的内容&#xff0c;下面我们继续来介绍删除清理、导入导出、创建镜像等操作。 如何删除和清理镜像&#xff1f; 使用标签删除镜像 可以使用docker rmi 或者是 docker image rm 命令来删除镜像&#x…

Spring源码之XML文件中Bean标签的解析1

读取XML文件&#xff0c;创建对象 xml文件里包含Bean的信息&#xff0c;为了避免多次IO&#xff0c;需要一次性读取xml文件中所有bean信息&#xff0c;加入到Spring工厂。 读取配置文件 new ClassPathResource("applicationContext.xml")ClassPathResource是Sprin…

微信小程序nodejs+vue+uniapp高校食堂线上预约点餐系统

本次设计任务是要设计一个食堂线上预约点餐系统&#xff0c;通过这个系统能够满足管理员及学生的食堂线上预约点餐分享功能。系统的主要包括首页、个人中心、学生管理、菜品分类管理、菜品管理、关于我们管理、意见反馈、系统管理、订单管理等功能。 开发语言 node.js 框架&am…

Flink之RedisSink

在Flink开发中经常会有将数据写入到redis的需求,但是Flink官方并没有对应的扩展包,这个时候需要我们自己编译对应的jar资源,这个时候就用到了bahir,barhir是apahce的开源项目,是专门给spark和flink提供扩展包使用的,bahir官网,这篇文章就介绍下如何自己编译RedisSink扩展包. 下…

Prometheus服务器、Prometheus被监控端、Grafana、Prometheus服务器、Prometheus被监控端、Grafana

day03 day03Prometheus概述部署Prometheus服务器环境说明&#xff1a;配置时间安装Prometheus服务器添加被监控端部署通用的监控exporterGrafana概述部署Grafana展示node1的监控信息监控MySQL数据库配置MySQL配置mysql exporter配置mysql exporter配置prometheus监控mysql自动…

spring security + oauth2 使用RedisTokenStore 以json格式存储

1.项目架构 2.自己对 TokenStore 的 redis实现 package com.enterprise.auth.config;import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis…

Spring Boot、Spring Cloud、Spring Alibaba 版本对照关系及稳定兼容版本

Spring Boot、Spring Cloud、Spring Alibaba 版本对照关系及稳定兼容版本 引言 在 Java 生态系统中&#xff0c;Spring Boot、Spring Cloud 和 Spring Alibaba 是非常流行的框架&#xff0c;它们提供了丰富的功能和优雅的解决方案。然而&#xff0c;随着不断的发展和更新&…

如何建立含有逻辑删除字段的唯一索引

业务场景 在实际工作当中&#xff0c;遇到一个场景&#xff0c;就是在用户注册时&#xff0c;名字要全局唯一&#xff0c;当然&#xff0c;我们是可以对用户进行删除的&#xff0c;你会怎么去做&#xff1f; 分析 一般来说&#xff0c;我们可以在用户注册请求时&#xff0c…

基于时空RBF神经网络的混沌时间序列预测(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【阵列信号处理】空间匹配滤波器、锥形/非锥形最佳波束成形器、样本矩阵反演 (SMI) 研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

chrome扩展在popup、background、content之间通信解决传输文件问题

文章目录 背景介绍案例介绍代码示例popup页面&#xff0c;上传文件页面popup页面&#xff0c;js上传代码&#xff0c;file文件转base64background监听消息&#xff0c;base64转file文件&#xff0c;axios上传 附-转base64后直接下载 背景介绍 示例扩展API版本MV2。 以弹…

3d 地球与卫星绕地飞行

1 创建场景 2 创建相机 3 创建地球模型 4 创建卫星中心 5 创建卫星圆环及卫星 6 创建控制器 7 创建渲染器 <template><div class"home3dMap" id"home3dMap"></div> </template><script> import * as THREE from three impo…

GD32F103*固件库移植μCOS-Ⅲ详细教程与解析(最终版本已上传,可下载)

GD32F103*固件库移植μCOS-Ⅲ详细教程与解析&#xff08;最终版本已上传&#xff0c;可下载&#xff09; GD32F103*移植μCOS-Ⅲ详细教程与解析&#xff0c;欢迎指正 文章目录 GD32F103*固件库移植μCOS-Ⅲ详细教程与解析&#xff08;最终版本已上传&#xff0c;可下载&#x…

appium自动爬取数据

爬取类容&#xff1a;推荐知识点中所有的题目 爬取方式&#xff1a;appium模拟操作获取前端数据 入门级简单实现&#xff0c;针对题目和答案是文字内容的没有提取出来 适用场景;数据不多&#xff0c;参数加密&#xff0c;反爬严格等场景 from appium import webdriver impor…

神经概率语言模型

本文主要参考《A Neural Probabilistic Language Model》这是一篇很重要的语言模型论文,发表于2003年。主要贡献如下: 提出了一种基于神经网络的语言模型&#xff0c;是较早将神经网络应用于语言模型领域的工作之一&#xff0c;具有里程碑意义。采用神经网络模型预测下一个单词…