进程的属性

一、进程状态

CPU执行进程代码不是把进程代码执行完毕,才开始执行下一个,而是给每一个进程预分配一个时间片,基于时间片,进行调度轮转。 

并行和并发

并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行。

并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发。

时间片

Linux/windows民用级别的操作系统是分时操作系统,调度任务追求公平。

运行(进程放在运行队列中)

只要进程在运行队列中,该进程就叫做运行状态,可以被CPU随时调度 。

阻塞(进程放在设备的等待队列中)

例如进程程序里面有scanf函数,其底层封装访问键盘的接口,对外部设备进行读取信息的操作,当键盘中没有信息输入的时候,进程被放置到外设结构体的等待队列中,这个过程便就是阻塞的过程。

挂起

挂起的背景:内存资源严重不足的时候。

例如在内存中,多个进程处于阻塞状态时,会被换出到磁盘中,当访问到外部设备信息的时候,再被换入到磁盘中(磁盘中有个swap分区专门进行换出换入操作)从而用时间换空间,因为换入换出的本质是IO

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

R运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。 

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

 该进程可以被杀掉:

 

D磁盘休眠状态(Disk sleep):有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。(防止数据丢失)

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

X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态。

Z(zombie)-僵尸进程

僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程(使用wait()系统调用)没有读取到子进程退出的返回代码时就会产生僵死(尸)进程。(通俗点说就是,子进程退出了,子进程的代码和数据都被释放,但是父进程仍然管理着子进程的PCB,这使得内存资源被无效占用,从而引发了系统层的内存泄漏)

僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态

所以需要父进程读取子进程的信息后,子进程退出才行。

补充说明:

进程退出时,代码不会被执行了,首先可以立即释放的就是进程对应的程序信息数据。进程退出,要有退出信息(进程的退出码)保存在自己的task_struct内部,管理结构task_struct必须被操作系统维护起来,方便用户未来进行获取进程退出的信息。

进程创建时,先创建内核数据结构再添加代码和数据。进程退出时先释放代码和数据,然后就是内核数据结构。将代码数据释放,内核数据结构维护的状态就是僵尸状态。

创建维持30秒的僵死进程例子

#include <stdio.h>
#include <stdlib.h>
int main()
{
    pid_t id = fork();
    if(id < 0){
        perror("fork");
    return 1;
    }
    else if(id > 0){ //parent
        printf("parent[%d] is sleeping...\n", getpid());
        sleep(30);
    }else{
        printf("child[%d] is begin Z...\n", getpid());
        sleep(5);
        exit(EXIT_SUCCESS);
    }
    return 0;
}

僵尸进程危害

进程的退出状态必须被维持下去,因为他要告诉关心它的进程(父进程),你交给我的任务,我办的怎么样了。可父进程如果一直不读取,那子进程就一直处于Z状态

维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说,Z状态一直不退出,PCB一直都要维护

一个父进程创建了很多子进程,就是不回收,就会造成内存资源的浪费。因为数据结构对象本身就要占用内存,想想C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空间!

孤儿进程

父进程先退出,子进程就称之为“孤儿进程。

孤儿进程被系统接管,从而变成后台进程。之所以要被系统接管是因为要回收它的PCB。

三、进程优先级

基本概念

1、cpu资源分配的先后顺序,就是指进程的优先权(priority)。
2、优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。
3、还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能。

系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高
效完成任务,更合理竞争相关资源,便具有了优先级

查看系统进程

UID : 代表执行者的身份(表面进程是谁启动的,linux下一切皆文件,文件会记录下拥有者,所属组和对应的权限,所有操作都是进程的操作,进程会记录是谁启动的我)
PID : 代表这个进程的代号
PPID :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
PRI :代表这个进程可被执行的优先级,其值越小越早被执行
NI :代表这个进程的nice值

优先级

PRI and NI

PRI也还是比较好理解的,即进程的优先级,或者通俗点说就是程序被CPU执行的先后顺序,此值越小进程的优先级别越高。

那NI呢?就是我们所要说的nice值了,其表示进程可被执行的优先级的修正数值。

PRI值越小越快被执行,那么加入nice值后,将会使得PRI变为:PRI(new)=PRI(old)+nice;这样,当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行。所以,调整进程优先级,在Linux下,就是调整进程nice值。nice其取值范围是-20至19,一共40个级别。

pri(最终)=pri(default80)+nice

nice范围:[-20,19]40个数字

需要强调一点的是,进程的nice值不是进程的优先级,他们不是一个概念,但是进程nice值会影响到进程的优先级变化。可以理解nice值是进程优先级的修正修正数据

用top命令更改已存在进程的nice:进入top后按“r”–>输入进程PID–>输入nice值

四、进程切换

前提:

时间片到了,进程就要切换,Linux是基于时间片调度轮转的,一个进程在时间片到了的时候,不一定跑完了,可以在任何地方重新调度切换。

感性理解

切换就是保存上下文数据和恢复上下文数据的过程

切换过程的理解

进程在运行时,会有很多的临时数据,都在cpu的寄存器中保存。其中eip(pc)中保存的是当前正在执行指令的下一条指令的地址。ir是指令寄存器,保存的就是正在执行的指令。CPU内部的寄存器的数据,是进程执行时的瞬时状态信息数据(上下文数据)。CPU里面有很多寄存器,但是寄存器不等于寄存器里面的数据。

进程切走时:将相关寄存器的内容保护起来;切回时:将历史保存的寄存器数据,恢复到寄存器中。中间所需的保护代码的容器并不在CPU内部(可以这么理解:进程的上下文寄存器数据,被保存到了当前进程的PCB中)。所以每次切换时,每次保存完上下文数据的时候CPU都是全新的。

Linux第一代内核: 

五、Linux的调度算法

一开始,active指针指向array[0],expired指针指向array[1]。

优先级

普通优先级:100~139(我们都是普通的优先级,想想nice值的取值范围,可与之对应)

实时优先级:0~99

活动队列

1、时间片还没有结束的所有进程都按照优先级放在该队列。
2、nr_active: 总共有多少个运行状态的进程
3、queue[140]: 一个元素就是一个进程队列,相同优先级的进程按照FIFO规则进行排队调度,所以,数组下标就是优先级

从该结构中,选择一个最合适的进程的过程:

1. 从0下标开始遍历queue[140]
2. 找到第一个非空队列,该队列必定为优先级最高的队列
3. 拿到选中队列的第一个进程,开始运行,调度完成!
4. 遍历queue[140]时间复杂度是常数!但还是太低效了!

5、 bitmap[5]:一共140个优先级,一共140个进程队列,为了提高查找非空队列的效率,就可以用5*32个比特位表示队列是否为空,这样,便可以大大提高查找效率!

过期队列

1、过期队列和活动队列结构一模一样
2、过期队列上放置的进程,都是时间片耗尽的进程
3、当活动队列上的进程都被处理完毕之后,对过期队列的进程进行时间片重新计算

active指针和expired指针

1、active指针永远指向活动队列
2、expired指针永远指向过期队列
3、可是活动队列上的进程会越来越少,过期队列上的进程会越来越多,因为进程时间片到期时一直都存在的。
4、没关系,在合适的时候,只要能够交换active指针和expired指针的内容,就相当于有具有了一批新的活动进程!

Linux链式结构

这样设计的好处是:一个进程,既可以在全局链表中,又可以在任何一个其他数据结构中,只要加结点字段即可。 

总结:

在系统当中查找一个最合适调度的进程的时间复杂度是一个常数,不随着进程增多而导致时间成本增加,我们称之为进程调度O(1)算法

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

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

相关文章

设计小白必看!一文教你区分原型图和UI图

产品设计过程中&#xff0c;产品经理或UI设计师常常需要在不同的设计阶段产出不同的原型图和UI图。初入职场的产品小白或UI小白很容易将原型图和UI图混淆&#xff0c;不能完全区分它们各自的作用&#xff0c;从而影响了设计流程的效率和效果。本文将详细解析原型图与UI图的定义…

【DS】哈希表,哈希桶的实现

目录 哈希概念哈希冲突哈希函数负载因子哈希冲突的解决闭散列开散列 哈希表闭散列的实现哈希表的结构哈希函数构造函数查找插入删除 哈希表开散列的实现哈希表的结构查找插入删除 哈希表的表长建议是素数 平衡二叉树的学习中&#xff0c;学习及模拟实现了AVL树和红黑树&#xf…

uni-app写的微信小程序如何体积太大如何处理

方法一&#xff1a;对主包进行分包处理&#xff0c;将使用url: /pages/components/equipment/equipment跳转页面的全部拆分为分包&#xff0c;如url: /pagesS/components/equipment/equipment 在pages.json中添加 "subPackages": [{ "root"…

STM32项目实战:基于STM32F4的智能灯光控制系统(LVGL),附项目教程/源码

《智能灯光控制系统_STM32F4》项目完整文档、项目源码&#xff0c;点击下方链接免费领取。 项目资料领取https://s.c1ns.cn/jjQK7 STM32项目实战之“智能灯光控制系统”&#xff08;基于STM32F4&#xff09; 今天小编来分享一个《智能灯光控制系统》的项目案例&#xff0c;硬件…

如何批量下载采集淘宝图片?3个方法可以帮助你

如何批量下载采集淘宝图片&#xff1f;在现代电子商务的背景下&#xff0c;淘宝作为中国最大的在线购物平台之一&#xff0c;承载了数以亿计的商品和信息。对于从事电商运营、市场推广或网络营销的人员而言&#xff0c;采集淘宝图片已经成为日常工作中的重要任务。这不仅是为了…

Jenkins pipeline语法笔记

Jenkins pipeline 简介Jenkins Pipeline 优势DSL 是什么 pipeline支持两种语法&#xff1a;声明式pipeline语法&#xff1a;Pipelineagent Pipeline 声明式语法DeclarativeenvironmentoptionsparameterstriggerstoolsinputwhenParallel Pipeline Scripted语法创建一个简单的 Pi…

(38)MATLAB分析带噪信号的频谱

文章目录 前言一、MATLAB仿真代码二、仿真结果画图总结 前言 本文给出带噪信号的时域和频域分析&#xff0c;指出频域分析在处理带噪信号时的优势。 首先使用MATLAB生成一段信号&#xff0c;并在信号上叠加高斯白噪声得到带噪信号&#xff0c;然后对带噪信号对其进行FFT变换&…

数据结构:跳表

数据结构&#xff1a;跳表 跳表实现类架构构造函数析构函数查找插入删除 总代码 跳表 在传统的链表中&#xff0c;不论单链表还是双链表&#xff0c;查询时都要O(N)的时间复杂度&#xff0c;就算是一个有序链表&#xff0c;由于无法像数组一样定址&#xff0c;无法进行二分查找…

学习最新vue20.17.0-事件处理

vue中文官网事件处理 | Vue.js (vuejs.org) 我在官网基础上,添加些代码,方便初学者学习,能够快速理解官网内容,掌握自己所需要的知识,以便节省宝贵的时间。 事件处理 监听事件 我们可以使用 v-on 指令 (简写为 @) 来监听 DOM 事件,并在事件触发时执行对应的 JavaScript…

Anaconda3与PyCharm安装配置

参考文章 Anaconda3与PyCharm安装配置保姆教程 参照上面文章&#xff0c;安装好Anaconda3和PyCharm环境 下面重点记录下环境配置 1&#xff0c;在window系统菜单中选择Anaconda Prompt&#xff0c;而不是Anaconda Powershell Prompt 2, 打开Anaconda Prompt&#xff0c;输…

[网络基础]——什么是IP路由,路由优先级,度量值详解

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;网络通信基础TCP/IP专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年10月14日15点23分 路由器扮演着至关重要的角色&#xff0c;它不仅负责将数据包从源地址转发到目的地址&#xff0c;还…

wsl1升级到wsl2步骤

1、进入到windows功能界面&#xff08;winr&#xff1a;输入cmd&#xff0c;到界面里面输出control&#xff09; 这几个选项勾选上&#xff0c;然后自动重启电脑 2、下载WSL2内核安装包 前往此链接&#xff0c;然后点击下图的下载链接&#xff0c;下载这个更新包后用管理员权…

美畅物联丨剖析 GB/T 28181 与 GB 35114:视频汇聚领域的关键协议

我们在使用畅联云平台进行视频汇聚时&#xff0c;经常会用的GB/T 28181协议&#xff0c;前面我们写了关于GB/T 28181的相关介绍&#xff0c;​ 详见《畅联云平台&#xff5c;关于GB28181你了解多少&#xff1f;》。 ​最近也有朋友向我们咨询GB 35114协议与GB/T 28181有什么不同…

详细分析Redisson分布式锁中的renewExpiration()方法

目录 一、Redisson分布式锁的续期 整体分析 具体步骤和逻辑分析 为什么需要递归调用&#xff1f; 定时任务的生命周期&#xff1f; 一、Redisson分布式锁的续期 Redisson是一个基于Redis的Java分布式锁实现。它允许多个进程或线程之间安全地共享资源。为了实现这一点&…

闯关leetcode——118. Pascal‘s Triangle

大纲 题目地址内容 解题代码地址 题目 地址 https://leetcode.com/problems/pascals-triangle/description/ 内容 Given an integer numRows, return the first numRows of Pascal’s triangle. In Pascal’s triangle, each number is the sum of the two numbers direct…

2.Java--入门程序

一、开发Java程序 步骤&#xff1a; 1.编写代码 其中第一行的HelloWorld叫类名&#xff0c;下面的框架叫main()方法&#xff0c; 类名要和文件名一致&#xff0c; 2.编译代码 用Javac进行编译&#xff0c;将编写的代码保存之后&#xff0c;打开WindowsR输入cmd 用cd文件夹…

SPP与SPPF的区别?Anchor based和Anchor free的区别?

SPP与SPPF的区别&#xff1f; spp是何凯明提出来的&#xff0c;名为空间金子塔&#xff0c;有效避免了对图像区域的裁剪、缩放操作导致的图像失真等问题。 解决了卷积神经网络对图相关重复特征提取的问题&#xff0c;大大提高了产生候选框的速度&#xff0c;且节省了计算成本。…

razor TagHelper 汇总、HtmlHelper 汇总

Tag Helper Tag Helpers 的范围由 addTagHelper 和 removeTagHelper 进行控制&#xff0c;并且 “!” 为退出字符。 addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers // 手动高亮 asp-for 》》 Label <label asp-for"userName"></label>》》生…

九大排序之选择排序和归并排序

1.前言 每一次从待排序的数据元素中选出最小&#xff08;或最大&#xff09;的一个元素&#xff0c;存放在序列的起始位置&#xff0c;直到全部待排序的数据元素排完 。 本章重点&#xff1a; 堆排序和选择排序和归并排序 2.选择排序 基本思路 left和right记录区间的左端和右…

Opencv库的安装与vs项目配置(vs成功配置opencv库)

目录 一、下载安装opencv 1、下载 2、减压安装 3、环境变量配置 二、vs项目配置opencv 1、创建vs项目 2、配置opencv库 3、测试 其中&#xff1a;二、2、配置opencv库是最复杂的&#xff0c;有空需要搞清楚vs中配置不同地方的区别。 以下所有测试是opencv官方4.6.0 w…