12 状态优先级

news2024/12/27 12:04:40

概念

cpu需要执行很多进程,有很多进程排在队列中,每个进程加载后运行一定的时间段,然后切换下一个进程。cpu如何判断进程需不需要加载,什么时候加载,依靠进程的状态和优先级属性来判断,进程调度,就变成了在task_struct的队列中选择一个进程的过程

内核源码

为了弄明白正在运行的进程是什么意思,需要知道进程的不同状态,一个进程有几个状态,有时候也叫任务

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

新建:新建进程,还没有运行的时候

运行

阻塞:当一个进程被cpu执行时,需要磁盘、网卡、显卡等设备资源就绪才可以,就会进入其他队列等待,等待磁盘等资源就绪的队列就是阻塞队列。**等待非cpu资源就绪就叫做阻塞态。**比如一个scanf函数一直不输入,等待键盘资源,就是阻塞。程序卡死有时候也是等待网卡资源,也有可能是cpu被占用,得不到调度,或操作系统卡死

在这里插入图片描述

挂起:当内存不足的时候,OS通过适当的置换进程的代码和数据到磁盘,进程的状态就叫做挂起
cpu内存不足的时候,会将长时间不执行,还需要等待很长时间资源的进程代码和数据换出到磁盘。也就是电脑的swap分区,是操作系统预先留好的,保证cpu正常的运行,这时候cpu会比较慢。再回来运行时需要把数据拿回来才能正常运行。压力过大电脑会宕机

写一份循环代码,用上节的循环命令不断查看进程状态
在这里插入图片描述

R+的状态就是运行中,接着往循环内加一个printf或者scanf函数,cpu的执行速度是非常快的,大部分时间都是往屏幕打印等待键盘输入等阻塞状态

在这里插入图片描述
S的状态就是阻塞

+的意思是前台程序
**前台进程:**当这个程序运行的时候,输入其他命令就没作用
运行程序后面加一个&符号,表示在后台运行,这个时候就没有+号了

在这里插入图片描述后台进程停止需要发送kill信号,crtl+c没用
在这里插入图片描述

退出状态:

有了上面的状态描述,下面逐个解析源码对应的状态:

R运行状态(running):对应上面的运行态
S睡眠状态(sleeping):阻塞状态,可中断睡眠
什么是可中断睡眠,运行一个阻塞状态的程序,-l查看所有信号
在这里插入图片描述
发送19号停止信号
在这里插入图片描述
进程被强制停止了,也就是睡眠状态还会接受命令,可以被中断

D睡眠状态:深度睡眠,磁盘睡眠,不可被中断,不可以自动唤醒
这个和上面的S状态相反
当服务器压力过大的时候,操作系统会将一些长时间不就绪的进程杀掉,多数为等待硬盘资源就绪的进程,当正准备往硬盘写入数据被杀掉后,就会造成数据丢失。为了防止这种情况,就设置了一种D状态,操作系统遇到这种状态就不会误杀。常用于从硬盘读取数据的场景,只有当硬盘数据就绪完成后,才会改变状态。kill信号也不行,dd命令的进程就是这种状态

T暂停状态: 上面发送了19号信号的进程就是暂停状态
在这里插入图片描述
t调试状态: 暂停状态的一种,正在调试的进程显示的状态(需要程序是debug版才可以调试),打一个断点,运行到断点处

在这里插入图片描述

X终止状态: 瞬时性非常强, 因为有很多进程在运行,需要标注可以回收的进程,很难捕捉到,任务列表李看不到

Z僵尸状态: 一个进程已经退出,不允许被OS释放,处于一个被检测的状态。一般是为了父进程或OS来回收,需要检测运行的结果

#include <stdio.h>
  2 #include <unistd.h>
  3 #include <sys/types.h>
  4 
  5 int main()
  6 {
  7     pid_t pid = fork();
  8     if (pid == 0)
  9     {
 10             sleep(3);  
 11     }
 12     else if(pid > 0)                                 
 13     {
 14         while(1)
 15         {
 16             sleep(3);
 17         }  
 18     }      
 19 }         

上面的代码子进程三秒后会结束,父进程一直在运行,可以循环查看状态
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

上图是理论状态,字母是具体状态。创建就是进程没运行,fork的子进程如果还没运行就是创建
运行状态,退出或终止就是Z和X状态,阻塞就是S,挂起也是S,看数据在不在内存,不在的话,内存中是挂起,进程状态还是S。状态可以是在上面的很多之间不停转换

僵尸状态

一个比较特殊的状态,进程退出且父进程没有读取到返回代码就会产生僵尸进程
僵尸进程会以终止状态保存在进程表中,并且会一直等待父进程读取退出状态代码
所以,只要子进程退出,父进程还在运行,但父进程没有读取到子进程状态,子进程进入Z状态

僵尸进程危害

进程的推出态必须被维持下去,要告诉关心它的父进程任务完成情况,如果一直不读取,就处于Z状态。进程不退出,PCB一直要维护,一直不回收,就会造成内存资源浪费,后面会详细说明

孤儿状态

父进程提前退出,子进程还在运行,就叫孤儿进程
孤儿进程会被1号进程领养,就是系统的 init进程,系统本身,也会回收

int main()
  6 {
  7     pid_t pid = fork();
  8     if (pid == 0)
  9     {
 10         while(1)       
 11         {        
 12      
 13             sleep(3);
 14         }                                            
 15     }
 16     else if(pid > 0) 
 17     {
 18             sleep(3);
 19             exit(0);
 20            
 21     }                
 22 } 

当3秒父进程结束后,子进程的父进程立马变成了1号进程,这时变为后台进程,可以kill杀掉
在这里插入图片描述

为什么要被领养,未来子进程退出的时候父进程不在,需要领养来回收资源

进程优先级

基本概念

cpu资源分配的先后顺序,进程的优先权
优先权高的进程有优先执行的权利,配置进程优先权对多任务环境的linux很有用,可以改善系统性能
还可以吧进程运行到 指定的cpu上,可以大大改善系统整体性能

优先级= 老优先级+nice值

运行一个进程,ps -la查看优先级
在这里插入图片描述

UID: 代表执行者的身份
PID: 进程的标识符
PPID: 哪个进程衍生来的,父进程
PRI: 进程的优先级,越小越早执行
NI: 代表nice值

NI是进程可执行优先级的修正数值,意思是可以通过根据这个值来调整优先级
加入nice值后,PRI会变为:PRI(new)=PRI(old)+nice
调整优先级,就是调整nice值
nice取值范围是-20至19,一共40个级别

进程的nice值不是优先级,但是会影响优先级,是修正数据

设置优先级

进入top,按r输入进程pid,回车后输入nice值
在这里插入图片描述
sudo模式设置nice为-100后,变为了60
在这里插入图片描述

这是因为每次设置nice值,老的优先级都是从80开始算,最小优先级是-20,80-20就是60
优先级的调整不会太大,nice值范围固定。是为了尽量不打破系统的调度安排,避免恶意占用资源,也为了系统更稳定

其他概念

竞争性:系统进程数目众多,cpu资源少量,所以进程有竞争性,为了高效合理分配资源,有了优先级
独立性:多进程运行,独享各种资源,一个进程崩溃不会影响其他进程。互相不干扰
并行:多个进程在多个cpu下同时运行
并发:进程切换的方式,一段时间内,多个进程都得以推进

每个进程在cpu中运行的时间叫时间片,而这个运行时间并不是固定的,如果运行完毕就会出去。同时,有时高优先级的进程会抢占cpu,低优先级的出让。每个进程都会较为均衡的占用cpu

在这里插入图片描述

一个进程在cpu运行的时候,寄存器内一定保存了进程的临时数据信息,寄存器有可显寄存器,还有电脑内的不可显。这些临时数据就是进程a的上下文数据,进程a被切下来时,需要带走保存自己的上下文数据。为了下次回来的时候,能恢复上去,就能按照之后的逻辑继续执行,就如同没有中断过一样。上下文数据可以有多份,分别对应不同的进程

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

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

相关文章

Node.js与Webpack笔记(一)

这里使用的16.19.0版本&#xff0c;官网和github没找到&#xff0c;去黑马2023年课程里找 篇幅较大会卡&#xff0c;此篇幅不写Webpack部分&#xff0c;留着下一篇 初识 1.什么是Node.js? Node.js 是一个独立的 JavaScript 运行环境&#xff0c;能独立执行 JS 代码&#xff…

A/D转换

硬件电路模型 模数转换代码 main.c #include <REGX52.H> #include "LCD1602.h" #include "Delay.h" #include "XPT2046.h"unsigned int ADValue; int main(){LCD_Init();LCD_ShowString(1,1,"ADJ NTC RG");while(1){ADValue …

iOS 17.0 UIGraphicsBeginImageContextWithOptions 崩溃处理

在升级到iOS17后你会发现&#xff0c;之前版本运行的很好&#xff0c;这个版本突然会出现一个运行闪退。报错日志为*** Assertion failure in void _UIGraphicsBeginImageContextWithOptions(CGSize, BOOL, CGFloat, BOOL)(), UIGraphics.m:410 跟踪到具体的报错位置如下所示&a…

redis09 集群(cluster)

思维草图 为什么要使用集群 单台redis内存容量的限制单台redis并发写量太大有性能瓶颈 redis集群认识 redis集群是对redis的水平扩容&#xff0c;即启动N个redis节点&#xff0c;将整个数据分布存储在这个N个节点中&#xff0c;每个节点存储总数据的1/N。 如下图&#xff1…

win11部署自己的privateGpt(2024-0304)

什么是privateGpt? privategpt开源项目地址 https://github.com/imartinez/privateGPT/tree/main 官方文档 https://docs.privategpt.dev/overview/welcome/welcome PrivateGPT是一个可投入生产的人工智能项目&#xff0c;利用大型语言模型&#xff08;LLMs&#xff09;的…

Windows安装SSH教程

Windows安装SSH教程 一、SSH1.SSH简介2.SSH功能3.SSH验证3.1 第一种级别&#xff08;基于口令的安全验证&#xff09;3.2 第二种级别&#xff08;基于密匙的安全验证&#xff09; 4.SSH层次4.1 传输层协议 [SSH-TRANS]4.2 用户认证协议 [SSH-USERAUTH]4.3 连接协议 [SSH-CONNEC…

场景问题: VisualVM工具Profiler JDBC不是真实执行的SQL

1. 问题 诡异的问题表象&#xff1a; 前端反馈分页接口的Total字段一直为0 使用Visualvm中的 Profiler 注入到应用后&#xff0c;查看JDBC监控得到了分页接口执行的SQL&#xff0c;复制出来执行是55. 此时还没有注意到 IN 的范围中有一个特别的值 NULL &#x1f928; 2. 排查…

【运维必学】2.零基础搞IT运维之服务器操作系统基础知识储备

微信改版了&#xff0c;现在看到我们全凭缘分&#xff0c;为了不错过【全栈工程师修炼指南】重要内容及福利&#xff0c;大家记得按照上方步骤设置「接收文章推送」哦~ 文章目录&#xff1a; 温馨提示&#xff1a;作者最近开通的知识星球&#xff0c;全栈系列从门到实践教程将会…

QT----写完的程序打包为APK在自己的手机上运行

目录 1、qt安装android组件2、打开qt配置Android 环境3、手机打开开发者模式&#xff0c;打开usb调试&#xff0c;连接电脑4、运行代码 1、qt安装android组件 qtcreater–工具-QTMaintenaceTool-startMaintenaceTool—登陆—添加或修改组件—找到android&#xff0c;安装 若是…

Windows环境MySQL全量备份+增量备份

目录 一、环境准备 1.1.安装MySQL 1.2.添加log-bin日志配置 二、创建测试数据库和表 2.1.创建测试数据库 2.2.创建测试数据表 三、全量备份恢复数据库 3.1.全量备份数据库 3.2全量恢复数据库 四、增量备份恢复数据库 4.1.增量备份数据库 4.2.增量恢复数据库 五、…

抽象步骤条(2.0版本)

vue3 router ele-plus 猜猜看为什么使用组件库&#xff01; 他呀的&#xff01;查看密码要自己写&#xff0c;验证信息也要自己写&#xff0c;所以说会用组件库会轻松一点&#xff0c;&#xff0c;&#xff0c; 代码如下 <template><div class"main"&g…

自动化构建平台(五)之Jenkins初始化配置以及插件安装操作

文章目录 前言一、安装必要插件二、系统参数配置三、全局工具配置总结 前言 上一篇我们介绍了Jenkins的安装和登录等相关操作&#xff0c;今天给大家介绍登录Jenkins后的一些初始化配置和插件安装的操作。因为如果要使用Jenkins来进行代码构建&#xff0c;必须先安装相关的插件…

WebDAV之π-Disk派盘+人生Life

人生Life是一款日程软件,在这款待办的日程软件当中各种功能极为的完善,完全的足够用户在日常当中的使用,你的待办方面的各种内容都能够在软件上面进行规划和填充,通过待办事项来帮助用户提高在日常当中的效率,对于用户来说这款待办事项的软件是绝佳的选择。 π-Disk派盘 …

VScode---php环境搭建

文章目录 1.下载php Dehug;php server2.下载php环境3.配置环境变量5.配置php.ini文件6.设置vscode6.测试遇到的问题 1.下载php Dehug;php server 2.下载php环境 下载地址&#xff1a;https://www.php.net/downloads.php 3.配置环境变量 C:\Users\hacker>php -v PHP 8.3.3 (…

c++编程复习之字符数组:电报文字

电报文字 内存限制&#xff1a;128Mb 时间限制&#xff1a;1000s 提交&#xff1a;138 解决&#xff1a;13 题目描述 输入一行电报文字&#xff0c;将字母变成其下一字母&#xff08;如’aa’变成’bb’……’zz’变成’&#xff41;&#xff41;’其它字符不变&#xff09;。 …

【leetcode】随机链表的复制

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家刷题&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 点击查看题目 思路: struct Node* copyRandomList(struct Node* head) {struct Node* curhead;//1.copy原链…

温湿度传感器SHT21

SHT21是一款基于IIC的温湿度传感器&#xff0c;它的引脚及定义如下&#xff1a; 标准的IIC器件&#xff0c;没有其他多余的引脚&#xff0c;应用框图如下&#xff1a; 温度的测量范围是-40到125℃&#xff0c;湿度测量范围0-100%RH&#xff0c;具体参数及采样精度见下图&#x…

利用excel文件增量同步一个库的数据并自动校正两端数据库条数不一致

利用excel文件增量同步一个库的数据并自动校正两端数据库条数不一致 现在有sqlserver和mysql两个库上的表在进行同步&#xff0c;sqlserver上的是源表&#xff0c;mysql上是目标表。 我们就把sqlserver上的数据同步到mysql上 mysql 是没有数据的。 sqlserver的三个表只是创建了…

Java-集合/容器

集合的概念 当我们需要保存一组一样&#xff08;类型相同&#xff09;的元素的时候&#xff0c;我们应该使用一个容器来存储&#xff0c;数组就是这样一个容器。 数组的特点&#xff1a; 数组是一组数据类型相同的元素集合&#xff1b; 创建数组时&#xff0c;必须给定…

Rabbitmq消息丢失-生产者消息丢失(一)

说明&#xff1a;消息生产者在将数据发送到Mq的时候&#xff0c;可能由于网络等原因造成数据投递失败。 消息丢失大致分三种&#xff1a;这里说的是生产者消息丢失&#xff01; 分析原因&#xff1a; 1.有没有一种可能&#xff0c;我刚发送消息&#xff0c;消息还没有到交换…