操作系统理论:Linux进程与进程状态(进程调度的大O(1)算法数据结构模型)

news2024/11/17 0:18:40

在这里插入图片描述

文章目录

  • 一.进程的基本概念
    • 进程间的基本关系:父子关系
  • 二.进程状态
    • (1)进程的运行状态R
      • Linux进程调度的大O(1)算法数据结构模型(运行队列哈希桶):
      • 进程的运行时间片
    • (2)进程的睡眠状态(S和D)
    • (3)进程的僵尸状态和死亡状态

一.进程的基本概念

  • 冯诺依曼体系的计算机在运行时,内存中会预加载许多程序(数据+运算指令集),然而CPU同一时刻只能执行一个程序(多个程序竞争CPU资源),此时就需要操作系统对内存中的诸多程序进行管理,让CPU资源得到合理的分配,于是便有了进程的概念:

    • 进程:描述程序的结构体对象(PCB结构体)和其所指向的程序(数据与运算指令集)
    • 在Linux中PCB结构体被命名为task_struct
  • 进程的PCB结构体在操作系统中会被组织进各种数据结构,同一个PCB结构体对象会同时位于多个数据结构中,比如:在这里插入图片描述

  • 操作系统对进程进行管理是通过对PCB结构体对象形成的数据结构进行增删查改实现的

  • Linux中进程的PCB通过PID(一个数字)唯一地标识:在这里插入图片描述

进程间的基本关系:父子关系

  • Linux系统中,一个进程可以通过库函数fork()创建子进程
    • pid_t fork(void);
    • 一个进程通过fork函数创建子进程后,父子进程共享fork()函数所在的代码语句以及其后的代码段
    • fork函数返回值说明:若子进程创建成功,frok函数在父进程中返回子进程的PID,在子进程中返回0,若子进程创建失败,则fork函数在父进程中返回-1
    • 子进程刚被创建时,会共享父进程的所有数据,后续子进程对于父进程的数据会进行写时拷贝
    • 根据父子进程中fork()返回值的不同,我们便可以令父子进程后续执行不同的代码段
int main()
{
  printf("hello world\n");
  size_t childPid = fork();//创建子进程
  if(childPid == 0)
  {
    //子进程执行的代码段
    while(1)
    {
       printf("我是子进程,Pid:%d,PPid:%d\n",getpid(),getppid());
       sleep(1);
    }
  }
  else
  {
    //父进程执行的代码段
    while(1)
    {
       printf("我是父进程,Pid:%d,PPid:%d\n",getpid(),getppid());
       sleep(1);
    }
  }

  return 0;
}

在这里插入图片描述

  • 运行状态:在这里插入图片描述
    在这里插入图片描述
  • 一个父进程可以有多个子进程,而一个子进程只有唯一的父进程,在操作系统中,依据父子进程的关系,PCB结构体对象会形成一个树形数据结构
  • 总之,在操作系统中,PCB结构体对象处于众多数据结构交织成的网中

二.进程状态

  • 进程状态总览(Linux操作系统):在这里插入图片描述

(1)进程的运行状态R

  • CPU一次只执行一个进程,一个CPU对应唯一一个运行队列(Linux中实质上是一个哈希桶),处于运行状态的进程的PCB结构体会被链入运行队列中,操作系统会依次调度运行队列中PCB结构体所指向的程序,将其交给CPU执行运算.
  • 进程的PCB会记录该进程的调度优先级(一个整数),进程的调度优先级会影响其在运行队列中的位置.
  • Linux中的进程优先级分为140个等级,其中0级到99级分给实时进程,100级到139级分给非实时进程
    • 140个等级对应140条运行队列分支(140条运行队列分支以哈希桶的结构进行组合)
    • 进程task_struct运行队列中的位置由其动态优先级决定在这里插入图片描述

Linux进程调度的大O(1)算法数据结构模型(运行队列哈希桶):

在这里插入图片描述

  • 在Linux内核中还有一个160个比特位大小的位图用于记录run哈希桶中的各个队列是否为空,一旦run哈希桶中的队列都为空,就交换指向run和tem两个数组的指针,然后继续执行进程调度
  • 得益于上图所示的数据结构,Linux操作系统无须对各个task_struct结构体进行依据优先级的快速排序,同时可以在任意时刻以O(1)的时间复杂度快速定位某个优先级的进程所在的分支运行队列(同时进行O(1)的队列判空),task_struct结构体对象的入队出队操作也是O(1)的时间复杂度,实现了Linux操作系统高效的进程调度机制

进程的运行时间片

  • 每个进程都有一个运行时间片(比如20ns),进程的时间片决定了CPU对其执行运算的单次最长时间,一个进程在CPU中完成了一个时间片的运算后就会暂时退出运行队列等待下一次调度
  • 有了时间片的限制,在一定时间段内(比如20ms),所有在运行队列中的进程都会被CPU执行运算一次,形成了进程的并发执行,CPU资源因此得到了合理的分配充分地使用
  • 我们感觉到电脑同时运行着多个程序,其实本质上是CPU在根据进程时间片极速地遍历执行着每一个进程而形成的进程并发的结果.

(2)进程的睡眠状态(S和D)

  • Linux系统中进程的睡眠状态对应着操作系统学科理论中的进程阻塞状态
  • CPU的运算速度数据流动速度是不对等的,因此进行数据交互的进程时常会处于等待反馈信息的状态
  • 当一个进程处在等待某种资源的状态时,其PCB结构体就会退出运行队列进入到阻塞队列中,比如某个进程需要键盘输入数据,这时它就会进入到键盘的阻塞队列中
  • 操作系统中,阻塞队列的数量是不确定的,系统中有多少种通信过程,就存在多少种阻塞队列:在这里插入图片描述
  • Linux中位于阻塞队列中的进程处于可中断睡眠状态(S状态),当系统内存不足时,操作系统会将一些处于阻塞队列中的进程对应的程序(数据和指令集)暂时存放到swap磁盘分区中,进程进入挂起状态
  • Linux操作系统在内存不足时,还会选择性地杀死一些位于阻塞队列中的进程,如果某个进程执行的是非常重要的任务(比如向磁盘中写入重要数据时,等待磁盘反馈),那么就需要将该进程标记为不可中断睡眠状态(D状态),处于不可中断睡眠状态的进程在被执行结束前不会相应操作系统的请求

(3)进程的僵尸状态和死亡状态

  • Linux系统中,当一个父进程的子进程终止时,该子进程就会进入僵尸状态(Z状态),Z状态的进程会等待其父进程来回收其PCB结构体中的终止信息(以便判断它是正常终止还是异常终止),只有当父进程处理了它的终止信息,子进程才会由Z状态进入死亡状态(X状态),这时,操作系统才会将子进程所占用的内存资源完全回收
  • 如果父进程一直不处理僵尸子进程的终止信息,那么僵尸子进程PCB结构体以及相关数据就会一直留在内存中,造成内存泄漏
  • 如果父子进程中的父进程率先终止了,其子进程就会被托孤给操作系统,成为操作系统的子进程,这样的进程称为孤儿进程
    在这里插入图片描述

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

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

相关文章

基于C语言 --- 自己写一个三子棋小游戏

C语言程序设计笔记---019 初阶三子棋小游戏(开源)1、arr_main.c程序大纲2、arr_game1.h3、arr_game1.c3.1、 自定义初识化函数 InitBoard( ) 和 自定义显示函数 DisPlayBoard( )3.2、 自定义玩家下棋函数 PlayerMove( )3.4、 自定义电脑下棋函数 ComputerMove( )3.5、 输赢判断…

成为一名黑客(网络安全),需要掌握哪些黑客技能?

前言 黑客技能是一项非常复杂和专业的技能,需要广泛的计算机知识和网络安全知识。你可以参考下面一些学习步骤,系统自学网络安全。 在学习之前,要给自己定一个目标或者思考一下要达到一个什么样的水平,是学完找工作(…

使用DataX实现mysql与hive数据互相导入导出

一、概论 1.1 什么是DataX DataX 是阿里巴巴开源的一个异构数据源离线同步工具,致力于实现包括关系型数据库(MySQL、Oracle 等)、HDFS、Hive、ODPS、HBase、FTP 等各种异构数据源之间稳定高效的数据同步功能。 1.2 DataX 的设计 为了解决异构数据源同步问题&#xf…

【外卖系统】分类管理业务

公共字段自动填充 需求分析 对于之前的开发中,有创建时间、创建人、修改时间、修改人等字段,在其他功能中也会有出现,属于公共字段,对于这些公共字段最好是在某个地方统一处理以简化开发,使用Mybatis Plus提供的公共…

简单记录牛客top101算法题(初级题C语言实现)判断回文字符串 反转字符串 合并两个有序的数组

1. 判断是否为回文字符串 给定一个长度为 n 的字符串,请编写一个函数判断该字符串是否回文。如果是回文请返回true,否则返回false。   字符串回文指该字符串正序与其逆序逐字符一致。 //示例 输入:"ranko" 返回值:fa…

DevOps系列文章之 自动化测试大全(单测和集成测试)

自动化测试业界主流工具 核心目标: 主要是功能测试和覆盖率测试 业界常用主流工具 GoogleTest GoogleTest是一个跨平台的(Liunx、Mac OS X、Windows 、Cygwin 、Windows CE and Symbian ) C单元测试框架,由google公司发布,为在不同平台上为编…

案例:缺陷个数与返工工作量强相关

某公司积累了21个项目缺陷个数与返工工作量的数据,如下表所示: 项目序号缺陷修复工时缺陷数1943314452299040536347446471385496071061370246774066812232189276652810830213781162678126111511381110514209032015144023516516078417710010301875601239…

3.Makefile变量的用法(附示例)

一、本节概要 本专栏所有内容围绕Makefile官方文档进行刨析,给出详细具体示例做辅助理解手撕Makefile官方手册 二、Makefile中的变量 1、没有使用变量的makefile 以下是不使用变量的makefile完整示例: edit: main.o kbd.o command.o display.o insert.o search.o files…

django channels实战(websocket底层原理和案例)

1、websocket相关 1.1、轮询 1.2、长轮询 1.3、websocket 1.3.1、websocket原理 1.3.2、django框架 asgi.py在django项目同名app目录下 1.3.3、聊天室 django代码总结 小结 1.3.4、群聊(一) 前端代码 后端代码 1.3.5、群聊(二&#xff09…

网络编程 IO多路复用 [epoll版] (TCP网络聊天室)

//head.h 头文件 //TcpGrpSer.c 服务器端 //TcpGrpUsr.c 客户端 通过IO多路复用实现服务器在单进程单线程下可以与多个客户端交互 API epoll函数 #include<sys/epoll.h> int epoll_create(int size); 功能&#xff1a;创建一个epoll句柄//创建红黑树根…

TypeScript算法题实战——剑指 Offer篇(5)

目录 一、平衡二叉树1.1、题目描述1.2、题解 二、数组中数字出现的次数2.1、题目描述2.2、题解 三、数组中数字出现的次数 II3.1、题目描述3.2、题解 四、和为s的两个数字4.1、题目描述4.2、题解 五、和为s的连续正数序列5.1、题目描述5.2、题解 六、翻转单词顺序6.1、题目描述…

《cuda c编程权威指南》01- 用gpu输出hello world

学习一门新语言的最好方式就是用它来编写程序。 目录 1. 使用cpu输出hello world 2. 使用gpu输出hello world 3. CUDA编程结构 1. 使用cpu输出hello world hello.cu #include <stdio.h>void helloFromCPU() {printf("hello world from cpu!\n"); }int m…

Zabbix分布式监控配置和使用

目录 1 Zabbix监控的配置流程2 添加主机组3 添加模板4 添加主机5 配置图形6 配置大屏7 新建监控项7.1 简介7.2 添加监控项7.3 查看数据7.4 图表 8 新建触发器8.1 概述8.2 添加触发器8.3 显示触发器状态 1 Zabbix监控的配置流程 在Zabbix-Web管理界面中添加一个主机&#xff0c;…

【Golang 接口自动化00】为什么要用Golang做自动化?

目录 为什么使用Golang做自动化 最终想实现的效果 怎么做&#xff1f; 写在后面 资料获取方法 为什么使用Golang做自动化 顺应公司的趋势学习了Golang之后&#xff0c;因为没有太多时间和项目来实践&#xff0c;怕止步于此、步Java缺少练习遗忘殆尽的后尘&#xff0c;决定…

【C++进阶之路】多态篇

文章目录 前言一、概念1.分类2.实现条件①重写虚函数1.1总结三重1.2 final与override ②父类的指针或者引用2.1普通调用VS多态调用 3.抽象类3.1. 纯虚函数3.2. 接口继承和实现继承 二、原理及使用1.虚函数表 —— 虚表2.默认成员函数2.1构造函数2.2析构函数 3. 多继承3.1普通的…

python速成之循环分支结构学习

循环结构 应用场景 我们在写程序的时候&#xff0c;一定会遇到需要重复执行某条或某些指令的场景。例如用程序控制机器人踢足球&#xff0c;如果机器人持球而且还没有进入射门范围&#xff0c;那么我们就要一直发出让机器人向球门方向移动的指令。在这个场景中&#xff0c;让…

AD21原理图的高级应用(六)原理图设计片段的使用

&#xff08;六&#xff09;原理图设计片段的使用 Altium Designer 的片段功能可以很方便地重复使用一些单元模块,其中包括原理图的电路模块、PCB(包括布线)和代码模块。例如在工程中需要设计电源模块,而别的工程中又恰好有比较完善的电源模块,这时就可以通过片段功能重复地使用…

一文了解 Android 车机如何处理中控的旋钮输入?

前言 上篇文章《从实体按键看 Android 车载的自定义事件机制》带大家了解了 Android 车机支持自定义输入的机制 CustomInputService。事实上&#xff0c;除了支持自定义事件&#xff0c;对于中控上常见的音量控制、焦点控制的旋钮事件&#xff0c;Android 车机也是支持的。 那…

测试|测试用例方法篇

测试|测试用例方法篇 文章目录 测试|测试用例方法篇1.测试用例的基本要素&#xff1a;测试环境&#xff0c;操作步骤&#xff0c;测试数据&#xff0c;预期结果…2.测试用例带来的好处3.测试用例的设计思路&#xff0c;设计方法&#xff0c;具体设计方法之间的关系**设计测试用…

linux设备驱动的poll与fasync

什么是fasync 在 Linux 驱动程序中&#xff0c;fasync 是一种机制&#xff0c;用于在异步事件发生时通知进程。它允许进程在等待设备事件时&#xff0c;不必像传统的轮询方式那样持续地查询设备状态。 具体来说&#xff0c;当进程调用 fcntl(fd, F_SETFL, O_ASYNC) 函数时&am…