【Linux】进程(3):运行,阻塞,挂起

大家好,我是苏貝,本篇博客带大家了解Linux进程(3),如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️
在这里插入图片描述


目录

  • (A) 运行(R)
  • 进程切换
  • (B)阻塞(S/D)
  • (C)挂起

下图是 操作系统 的5种状态
在这里插入图片描述

在Linux中,运行和就绪状态可以合并,用状态R表示。阻塞状态用S/D表示。终止状态用Z/X表示

(A) 运行(R)

下面的内容不是Linux调度的方法,是操作系统教材调度算法的一种。 因为这种调度算法比较简单,所以我们先了解这种

运行进程一定是在CPU里运行的,所以有一个CPU

运行进程时,要将自己的代码和数据从磁盘加载到内存中,操作系统为管理进程,会在内部为每个进程创建对应的内核数据结构task_struct,task_struct能够找到对应的代码和数据。
在这里插入图片描述

为了方便操作系统对进程的管理,管理进程变成了对链表(每个结点都是一个进程的task_struct)的增删查改。
在这里插入图片描述

新增一个进程就是将新进程的代码和数据加载到内存,再由操作系统提供对应的task_struct,再将task_struct连接到队列中
在这里插入图片描述

删除一个进程就是根据pid找到对应的进程,释放掉进程的task_struct和内存里的代码和数据的空间,再将链表重新链接起来

在这里插入图片描述

每个CPU都要维护一个运行队列。运行队列本身也是一个结构体
在这里插入图片描述

所以进程要运行,首先要将进程放入运行队列当中
在这里插入图片描述

往后CPU要调度一个进程,只要找到它对应的运行队列,将队列头部的进程的代码和数据加载到CPU里的寄存器中。严格意义上来讲,只要进程被放入CPU上,进程的状态就是R
在这里插入图片描述

但是很多操作系统的教材上会说:只要进程在运行队列中,进程的状态就是R。这里的R表示进程已经准备好了,可以随时被调度了。但在Linux中,并没有already状态(就绪状态),所以我们可以把就绪状态和运行状态压缩成一个状态。但如果实在要将这两个状态分开来的话,那么可以理解为只有在CPU上跑的是运行状态,在运行队列里的就是就绪状态

进程切换

一个进程一旦持有CPU,会一直运行到这个进程结束吗?不会,因为存在时间片轮转调度算法,该算法是基于时间片进行轮转调度的,核心思想是将CPU时间分成固定大小的时间片,每个进程在一个时间片内执行,如果时间片用尽而进程未完成,那么该进程就会被放到就绪队列的末尾,等待下一次轮到它执行。这种方式可以保证每个进程都有机会在CPU上执行,避免了某个进程长时间独占CPU的情况,提高了系统的公平性。

比如进程a是个死循环,时间片是2毫秒,那么2毫秒之后,操作系统会直接将进程a从CPU上剥离下来,重新列入运行队列的尾部,让下一个进程b进行我们的调度
在这里插入图片描述

这就是为什么哪怕我们电脑只有一个CPU,我们同时开着QQ,微信和网易云,如果QQ死循环了,微信和网易云还能正常使用的原因

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

如果1个计算机里有2个CPU,那么它们分别维护一个运行队列。也就是说,这2个CPU可以同时调度不同的程序
在这里插入图片描述

并行:任何时刻,都同时有多个进程在真的同时运行

现在我的电脑只有一个CPU(CPU内部会有非常多的寄存器,如:eax,eip,CR0~CR4等等),存在进程1和进程2
在这里插入图片描述

CPU先调度进程1,此时CPU的寄存器中会保存进程1的临时数据。但是在时间片内,进程1还没有执行完成,要从CPU上剥离,这时CPU会将寄存器内的临时数据存入进程的task_struct中,CPU的寄存器内的临时数据也叫进程的上下文,即将上下文数据存入task_struct中。等到再次被CPU调度时,CPU就会从上一次执行结束的位置开始执行。
再调度进程2,过程同上

进程在切换,最重要的一件事情:上下文数据的保护(CPU将寄存器中的临时文件存入task_struct)和恢复(上下文数据存入寄存器中)

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

拓展:
在这里插入图片描述

上面这个简单的C语言代码中,c是局部变量,那是通过什么能将c的值返回呢?寄存器

(B)阻塞(S/D)

在了解阻塞状态之前,先思考一个问题:我们使用C语言里的scanf函数,如果我们不在键盘上输入,那么该进程处于什么状态?

修改.c文件
在这里插入图片描述
在这里插入图片描述

我们发现,当scanf等待我们键盘输入时,进程状态是S
在这里插入图片描述

所以这本质上就是阻塞。这是在等待键盘资源是否就绪,简单来说就是键盘上有没有被用户按下的按键以及按键数据是否交给进程。

我们再来画一下冯诺依曼体系结构

先画出结构的倒数第一二层:硬件和驱动层(每个硬件的厂商都会写自己硬件的驱动程序)
在这里插入图片描述

我们知道,操作系统是管理软硬件资源的。管理软件:进程等。那操作系统是怎么管理硬件的呢?依旧是先描述,再组织。下面所写的并非是Linux内核的真正实现,而是它的原理的说明

比如说我们定义一个设备在操作系统的结构体。进程为什么能够等待设备资源,因为设备的结构体有等待队列
在这里插入图片描述

每个设备都有自己的struct device,操作系统为了将设备管理起来,将所有设备的struct device用指针联系起来。最终,对设备的管理就变成了对设备链表的增删查改

在这里插入图片描述

现在我们要启动testStatus进程,进程里面有scanf函数。该进程要被CPU调度,执行scanf()函数的时候发现要访问键盘资源,而操作系统检测键盘的工作状态发现它并不ok(用户没有在键盘上输入)

在这里插入图片描述

所以将该进程从运行队列中剥离出来,放入键盘的等待队列中。比如又有一个进程要等待磁盘资源,那么也要将该进程从运行队列中剥离出来,放入磁盘设备的等待队列中。所以,不是只有CPU才有运行队列,各种设备也有自己的等待队列
在这里插入图片描述

此时有2个进程不在运行队列,就不会被调度,因此叫这样的进程为阻塞进程。

等到用户按了键盘上的按键,通过驱动程序会被操作系统最先知道,知道之后,将设备的struct device的工作状态改为ok,再将在设备队列里的进程重新链回到运行队列中(这个过程叫唤醒),等CPU再次调度时,会执行scanf后续代码,将键盘设备的数据读取

在这里插入图片描述

阻塞和运行的状态变化,往往伴随着pcb被链入不同的队列中。入队列的不是代码和数据,而是进程的task_struct

(C)挂起

在这里插入图片描述

假设只有3个进程,如果此时操作系统内存特别吃紧,且进程处于阻塞态,那么操作系统会将内存中的代码和数据加载到磁盘的swap分区,内存中的代码和数据的空间会被释放,进程任然存在。这个过程叫唤出。

swap分区一般是内存的1-2倍大
在这里插入图片描述

如果进程等待的资源就绪了,开始被调度了,即状态由S变成R,那么进程对应的代码和数据会从swap分区加载到内存中。这个过程叫唤入
在这里插入图片描述


好了,那么本篇博客就到此结束了,如果你觉得本篇博客对你有些帮助,可以给个大大的赞👍吗,感谢看到这里,我们下篇博客见❤️

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

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

相关文章

在gitlab上发布npm二进制文件

❝ 允许奇迹发生 ❞ 大家好,我是「柒八九」。一个「专注于前端开发技术/Rust及AI应用知识分享」的Coder。 前言 还记得之前我们讲过如何在 npm 上发布二进制文件?吗。我们通过npm将我们之前在Rust 赋能前端-开发一款属于你的前端脚手架中生成Rust二进制文…

生物制药企业选择谷歌云的理由有哪些?

AI发展的这一年,科学家也紧随其后,透过AI拓展更多微观层面的生物学奥义,包括蛋白质折叠等。生物制药公司也加大了在药物研发领域的投入,其中一方面就是搭载云平台。那么,生物制药公司选择谷歌云的原因有哪些呢&#xf…

Python | Leetcode Python题解之第128题最长连续序列

题目: 题解: class Solution:def longestConsecutive(self, nums: List[int]) -> int:longest_streak 0num_set set(nums)for num in num_set:if num - 1 not in num_set:current_num numcurrent_streak 1while current_num 1 in num_set:curre…

Flutter基础 -- Dart 语言 -- 进阶使用

目录 1. 泛型 generics 1.1 泛型使用 1.2 泛型函数 1.3 构造函数泛型 1.4 泛型限制 2. 异步 async 2.1 异步回调 then 2.2 异步等待 await 2.3 异步返回值 3. 生成器 generate (了解) 3.1 同步生成器 sync* 使用 sync* 的场景 总结 3.2 异…

【C语言】编译与链接:深入理解程序构建过程

🔥引言 本篇将深入理解程序构建过程,以便于我们在编写程序的过程同时,理解底层是如何从程序的创建到生成可执行程序的。 🌈个人主页:是店小二呀 🌈C语言笔记专栏:C语言笔记 🌈C笔记专…

软件设计师-知识点

系统总线 系统总线分为三部分: 数据总线地址总线控制总线 主要作用:用于CPU、主存和外设部件之间的连接 DMA控制器/中断控制器(CPU) DMA控制器和中断控制器(CPU)发出的数据地址:主存物理地址 释:和I/O设备相关的数据都是直接读…

c++与c

命名空间的设置: 避免冲突 命名空间: 如果将变量全部定义在全局可能不安全,都可以进行修改。 如果将变量定义在局部,当出了大括号就不能使用。 所以说在定义一个命名空间的时候 定义函数,变量,命名空间…

软件3班20240603

经典 报错 404 大概率 就是 这图 的 路径 写错i了 package com.yanyu;import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import jav…

现货白银的交易时间有多连贯?

国际市场上的现货白银优势很多,它除了具备国内同类型品种所不具备的数十倍资金杠杆外,也基本上实现了全天24小时不间断的交易时间,所以投资者可以在全天候连贯的行情中,寻找属于自己的交易获利机会。 但对于内地的投资者来说&…

从 Lerna 到现代化:原生 Workspaces 和 Changesets 的高效协作

1. 背景 最近新接手的一些 monorepo 的库项目,项目是用 lerna 进行管理的,使用过程中有一些不丝滑的地方,包括: lerna 版本过旧,使用 4.0.0(现版本 8.1.3),功能差异过大&#xff0…

前端JS必用工具【js-tool-big-box】学习,检测密码强度

js-tool-big-box 前端工具库,实用的公共方法越来越多了,这一小节,我们带来的是检测密码强度。 我们在日常开发中,为了便于测试,自己总是想一个简单的密码,赶紧输入。但到了正式环境,我们都应该…

FullCalendar日历组件集成实战(8)

背景 有一些应用系统或应用功能,如日程管理、任务管理需要使用到日历组件。虽然Element Plus也提供了日历组件,但功能比较简单,用来做数据展现勉强可用。但如果需要进行复杂的数据展示,以及互动操作如通过点击添加事件&#xff0…

【算法每日一练】新月轩就餐

思路: 其实很容易想到是双指针或者双端队列。 我们设置一个type表示当前区间已经有了多少种厨师,同时还需要记录区间中每个元素出现的次数,然后比较棘手的是移动问题了,什么时候移动呢? 我们可以发现当区间当队头元…

手眼标定学习笔记

目录 标定代码: 手眼标定原理学习 什么是手眼标定 手眼标定的目的 eye in hand eye to hand AXXB问题的求解 标定代码: GitHub - pumpkin-ws/HandEyeCalib 推荐博文: https://zhuanlan.zhihu.com/p/486592374 手眼标定原理学习 参…

国产操作系统上Vim的详解01--vim基础篇 _ 统信 _ 麒麟 _ 中科方德

原文链接:国产操作系统上Vim的详解01–vim基础篇 | 统信 | 麒麟 | 中科方德 Hello,大家好啊!今天给大家带来一篇在国产操作系统上使用Vim的详解文章。Vim是一款功能强大且高度可定制的文本编辑器,广泛应用于编程和日常文本编辑中。…

记一次cms代码审计

000:前言 记录一次小型cms代码审计 001:任意文件删除 由于代码繁杂,不再一一展示 /app/controller/kindeditor.class.php 关键漏洞代码 public function delete() {$path ROOT_PATH.$_GET[pic];unlink($path);$flash M("flash&qu…

Postgre数据库初探

一、PostgreSQL介绍 PostgreSQL是以加州大学伯克利分校计算机系开发的POSTGRES, 版本 4.2为基础的对象关系型数据库管理系统(ORDBMS)。POSTGRES 领先的许多概念在很久以后才出现在一些商业数据库系统中。 PostgreSQL是最初的伯克利代码的开…

vscode编译c/c++找不到jni.h文件

解决办法: 一、下载JDK 访问Oracle官网的Java下载页面:Java Downloads | Oracle 选择适合您操作系统的JDK版本: 对于Windows,选择“Windows x64”或“Windows x86”(取决于您的系统是64位还是32位)。对于Linux&#…

RPM包方式离线部署gitlab

下载安装包 要求:可以联网,系统及版本与目标服务器一致。配置gitlab yum仓库 curl -s https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash 新建包存放目录 mkdir /root/gitlab 下载gitlab及相关安装包 …

老赛棍版端口,扫别人没扫到的资产

0x001 获取目标信息 因为某些敏感原因,这部分干脆以长沙为例,仅做查询方式参考。首先FOFA搜:region"Hunan" && city"Changsha",全部转换为C段后去重,就得到该城市的大致网段:…