什么是进程?

目录

进程

进程的特征, 概念

我们下面先简单介绍一下什么是进程

接下来看看一个程序的运行过程

进程的组成 

进程的状态和转换

进程的状态

进程状态的转换

​编辑

进程的组织方式 

进程控制

如何实现进程控制

为什么进程控制的过程需要一气呵成? 

进程控制的实现

原语类型和创建过程

进程间通信

什么是进程间通信

为什么进程通信需要操作系统支持? 

共享存储

消息传递 

管道通信 


进程

进程的特征, 概念

我们下面先简单介绍一下什么是进程

        首先你看到的qq.exe就是一个存储在磁盘里面的可执行文件, 它是一系列指令的集合. 而所谓的进程是动态的, 是程序的一次执行过程.

        例如我有一个qq.exe文件, 那么双击这个文件, 救护让操作系统去执行这个指令集合, 那么执行的过程就是进程, 也就是你在任务管理器中看到的一个个进程: 

        那么很多个执行文件一起执行, 那么就会产生很多进程, 为了管理这些进程, 操作系统会为他在们执行前分配一个唯一的进程id.

        当然, 他不只是分配了进程id, 操作系统背后还会记录各个进程的其他信息, 例如:

  • 还会记录 给这个进程分配了多少内存
  • 这些进程正在使用哪些IO设备. 
  • 进程正在使用哪些文件
  • CPU使用时间, 磁盘使用情况, 网络流量使用等等.

        为了统一管理这些信息, 操作系统会将各个进程的这些信息, 组织成为一种数据结构, PCB中, PCB也就是process control block, 中文翻译为进程控制块.

         PCB是操作系统级别的, 也就是说PCB是由操作系统管理的信息, 进程本身的指令集合和运行时候产生的数据才是自己的, 如下: 

  • 程序段: 也就是我们所说的 程序的代码 (最后还是会被编译成机器可以识别的指令序列)
  • 数据段: 也就是一个程序在运行期间产生的各种数据(例如 程序中定义的变量, 我们需要再内存中给他分配空间)

接下来看看一个程序的运行过程

        我们在学习c语言的时候肯定知道, 我们写好c语言的代码之后, 但是计算机是不认识这个代码的, 我们需要将其翻译成机器可以识别的二进制指令(一条高级语言代码翻译成机器指令可能会有多条) . 

来源:  RGSS 中执行机器码 - 知乎

         首先我们在编写程序的时候, 肯定会写这样的一些代码, 如int a = 10; a++; 之类的代码, 通过编译和链接,最终形成一个.exe的可执行文件,这个可执行文件是存放在硬盘中的。它里面内容就是机器可以识别的指令序列。

        如果要运行这个可执行文件,就需要将其加载到内存中去(这里啰嗦一句,这个过程就好比如你有一块电池,你想要用它,那么你就需要将其装载到遥控器中去使用它是一个道理):

         在加载到内存中的时候,操作系统会为改进程创建对应的PCB来存放进程的信息,然后将其指令序列读取到内存,(除此之外,在执行指令序列的时候,可能会产生额外的数据,例如我们创建的变量int i = 10;)然后cpu就从内存中读取这些指令来执行。

        完整的过程如下:

进程的组成 

        进程的组成既是:

  • PCB : 存储进程的信息
  • 程序段: 程序的指令序列
  • 数据段:进程在运行过程中 产生的各种数据

        进程是系统进行资源分配和调度的一个独立单位,PCB是进程存在的唯一标志。

进程的状态和转换

进程的状态

        我们首先来看看进程的状态有哪些(你可以类比一下java里面线程的状态有哪些)。

        从上面进程的概念中, 我们得知:

  1. 首先 磁盘或者硬盘中的一个可执行文件,需要先被加载到内存中去
  2. 然后操作系统为其创建PCB,然后分配内存空间并初始化PCB,这个创建进程的状态就称为创建态
  3. 这个时候,进程就创建完毕,此后该进程就进入就绪态,等待cpu来运行其指令
  4. cpu空闲的时候,就会为这些在就绪态的进程,让它上cpu运行
  5. 此时的进程就为运行态(正在执行指令序列
  6. 但是也不会一直都让一个进程在cpu上一直运行,如果一个进程在运行态的某个时刻,需要某个系统资源,但是这个资源正在被其他进程使用,但是当前进程没有这个资源又运行不了,那么在继续呆在cpu又什么都不干,操作系统就认为它在消耗cpu资源,就让他下去了,并让新的进程上cpu,此时下去的进程就为阻塞态
  7. 这个时候,如果这个进程需要的系统资源被释放了,那么这个进程又可以重新上cpu执行了,上了cpu之后,又重新变为运行态,直到指令集合执行完毕,此时该进程会发起exit系统调用,也就是请求操作系统终止当前进程。此时进程进入终止态,操作系统会让起下cpu,并回收资源。

省流: 可执行文件,创建态,就绪态,运行态/ 阻塞态,终止态。

进程状态的转换

进程的组织方式 

        上面我们了解了, 进程的几个状态, 这些状态在其pcb中 会存在一个变量来表示进程的当前的状态, 例如1表示创建态. 2表示就绪态, 3表示运行态 等等, 然后操作系统将各个进程的pcb管理起来, 如何将进程的pcb组织起来? 有两种方式.

链式存储: 

  • 对于状态为创建态的进程, 我们使用一个指针来指向他, 然后如果后续还有进程处于创建态的时候, 就将其插入到这个指针所维护的创建态进程链表中.
  • 对于就绪进程和阻塞队列也是如此. 
  • 其中阻塞队列的链表可能会因为阻塞的原因不同而分为多个不同类型的阻塞队列

索引存储:

 

进程控制

        实习进程的状态转换 

        进程的控制主要是对系统中所有的进程实施有效的管理, 它有创建新进程, 撤销已有进程, 实现进程状态转换等功能.

如何实现进程控制

        操作系统中使用原语来实现对进程的控制, 原语 就是一种特殊的程序, 它的执行具有原子性, 也就是说, 这段程序的运行必须一气呵成, 不可以中断. 

为什么进程控制的过程需要一气呵成? 

        我们知道, 进程的PCB中存在一个变量state来表示进程当前所处的状态, 然后操作系统通过链式方法来管理这些PCB的state, 如下: 

         现在有这样一个案例, 现在有一个进程处于阻塞态, 它等待被占用的资源被释放, 此时它的state为阻塞态, 如果这个资源被释放之后, 那么他就应该从阻塞态到就绪态.

        此时应该要经历这些东西: 

  • 该进程的在阻塞队列中的结点的state值应该变为 "就绪态" 所对应的值
  • 然后将此结点从阻塞队列 移出, 然后搬入就绪队列中.

        这两步缺一不可, 这里考虑 他们其中一个步骤失效

  • 首先在执行第一步的时候, 也就是将这个想要进入就绪态的进程的pcb的state设置为 "就绪态" 所对应的值, 但是设置完成之后, 就收到了操作系统的中断信号, 此时它的state为就绪态, 但是 目前还是在阻塞队列中, 这就不符合状态组织的逻辑

        所以需要使用原语来让其一气呵成.

进程控制的实现

        原语的执行具有原子性, 执行期间不能被中断, 可以使用 关中断指令开中断指令 这两个特权指令来实现

        cpu在运行的时候, 会一条一条的执行指令, 如下: 

        假如如果执行到 指令2的时候, cpu收到了外部的中断信号, 这个时候, cpu就会暂停执行当前的指令, 转而运行 中断处理程序, 等这个终端处理程序处理完成之后, 就继续往下面执行指令. 

        那执行到关中断时候, 会发生什么呢? 

        是的. 早cpu执行了关中断指令之后, 就不再检查中断信号, 知道执行到开中断指令之后, 才会执行检查. 执行了关中断指令之后, 然后执行指令a和指令b, 一直到执行开中断指令之后才会检查中断指令.

        如果这个指令a和指令b中间执行过程中出现了中断信号, 在执行完开中断指令之后, cpu才会去运行对应的中断处理程序, 此时指令a和指令b全部已经执行完了, 就保证了其执行的原子性./ 

        为什么关中断和开中断是特权指令? 特权指令只能由内核程序执行, 内核程序运行在内核态, 比较安全, 这个时候如果可以给用户态的程序执行开中断和关中断指令的话, 那么其就会一只霸占cpu浪费资源, 影响系统安全/

原语类型和创建过程

        前面提到我们使用原语来保证指令执行的原子性, 那么原语有哪些类型呢? 

  • 进程的创建
    • 创建原语
      • 申请空白PCB
      • 为新进程分配所需资源
      • 初始化PCB
      • 将PCB插入到就需队列
    • 引起进程创建的事件 的例子
      • 用户登录 : 分时系统中,用户登录成功,系统会建立为其建立一个新的进程
      • 作业调度 : 多道批处理系统中,有新的作业放入内存时,会为其建立一个新的进程
      • 提供服务 : 用户向操作系统提出某些请求时,会新建一个进程处理该请求
      • 应用请求 : 由用户进程主动请求创建一个子进程
  • 进程的终止
    • 撤销原语: 
      • 从PCB集合中找到其终止进程的PCB(找到其PCB)
      • 如果程序正在运行, 那么久立刻剥夺其cpu执行权, 将cpu资源分配给其他进程.
      • 同时操作系统在杀死一个进程的时候, 也会同时杀死其子进程(父子进程关系为一种树形结构)
      • 将该进程拥有的资源归还给父进程或者是操作系统
      • 然后删除PCB
    • 案例 : 
      • 正常结束 : 进程正常结束, 自己请求终止
      • 异常结束 : 整数除以0, 非法使用特权指令, 被操作系统强行杀死
      • 外界干预 : 用户手动杀死进程
  • 进程的阻塞和唤醒: 

  • 进程的切换: 
    • 切换原语: 
      • 将运行环境信息存入PCB
      • PCB移入对应的队列
      • 选择另外一个进程执行, 更新其PCB
      • 根据PCB恢复这个进程所需的环境
    • 案例: 
      • 进程时间片到了, 就会下处理机, 让另外一个进程上cpu运行
      • 有更高优先级的进程到达, cpu优先执行这个高优先级进程, 那么就会引起进程切换
      • 当前进程主动阻塞之后, 操作系统认为其长时间浪费系统资源, 让其下cpu, 让其他进程上cpu运行
      • 当前进程异常终止, 或者是主动请求终止, 这个进程都会下cpu, 此时会有一个新的进程上cpu运行.

进程间通信

什么是进程间通信

        一个正在运行的操作系统, 难免会有很多个进程在同时并行, 他们之间也难免需要进行一些通信, 这种通信, 就叫做进程间通信(IPC), 指的是两个进程之间产生了数据交互.

        便于理解, 这里列举一个例子: 

我们在使用微博的时候看到一篇文章, 突然我们很像分享给朋友看, 于是就点了右上角的 ... 然后选择了微信分享: 

然后:

        那么这个过程, 就从微博, 将微信唤起, 然后将微博文章的链接分享到了微信

        这个操作是需要操作系统的支持的.

为什么进程通信需要操作系统支持? 

        进程是分配系统资源的最基本单位(包括内存地址空间), 因此各个进程都拥有相互独立的地址内存空间. 所以进程a在运行的过程中是不能访问进程b的空间, 那么如何进行进程间通信?  

        那就需要操作系统来帮忙了.

那么操作系统提供了几种让进程可以相互进行数据交换的方式 : 

共享存储

  • 基于存储区的共享
  • 基于数据结构的共享

        一个进程申请一个共享存储区, 其他进程想要和此进程进行通信的时候, 只需要将数据写入这个内存共享区域即可: 

        然后另外一个进程就可以读取另外一个进程写入的数据.

但是会出现一个问题:

        两个进程同时往共享存储区域中的相同的地方进行写入, 那么就有可能会发生一个进程写入的数据将另外一个进程写入的数据给覆盖掉.

        那么就需要保证, 他们对这个共享存储区域的写操作是互斥的, 互斥的对象是进程对象. 比如说, 进程a在访问这个共享存储区的时候, 其他的进程是无法向这个共享内存区域中写入数据的.

        那么如何进行互斥操作? 操作系统提供了很多同步互斥工具: p,v操作        

        基于存储区的共享:操作系统在内存中划出一块共享存储区,数据的形式、存放位置都由通信进程控制,而不是操作系统。这种共享方式速度很快,是一种高级通信方式。

        当然我们也可以在共享区域的前提下, 将内存空间进行结构化, 例如共享区域只能存放一个长度为10的数组, 这种方式就叫做基于数据结构的共享, 但是通信的速度就变慢了, 因此基于数据结构的共享是一种低级通信

 总结:

  • 基于存储区的共享: 速度快, 灵活性高, 高级通信
  • 基于数据结构的共享: 速度慢. 灵活性低, 低级通信

消息传递 

        进程间的数据交换以格式化的消息(Message)为单位。进程通过操作系统提供的“发送消息/接收消息”两个原语进行数据交换。

格式化的消息由两部分组成: 

  •  消息头
  • 消息体

消息的传递又分为两种: 

  • 直接通信方式 : 进程要指明接收进程的id
  • 间接通信方式 : 通过"信箱" 间接的进行通信(又称信箱通信)

下面来看看直接通信方式是如何通信的: 

  • 每个进程的PCB中存在着一个类似于消息队列的结构, 用来接收其他进程的消息
  • 进程A将自己要发送的信息的消息体和消息头, 然后通过操作系统提供的发送原语, 并指明消息的接受者, 
  • 操作系统就会将消息挂在对应进程的消息队列中
  • 然后假设是进程B接收到这个消息, 那么进程B使用接收原语, 指明要接受哪个进程的消息, 操作系统就会到进程B对应的PCB中去寻找这条消息. 然后将消息复制到B的地址空间中

接下来是间接通信方式: 

  • 进程A和进程B都申请了一块空间, 用来当做接收消息的信箱
  • 进程A在自己的地址空间中填充好消息体和消息头
  • 然后进程A使用发送原语来指明要发送到哪个信箱
  • 假设此时进程A指明要发送给信箱A发送消息
  • 然后进程B指明要在信箱A中接受这条消息, 那么就完成了消息的传递

管道通信 

        这个懂得都懂, 可以简单理解为一个队列.

        其实这个"管道" 是一个特殊的共享文件, 又名为pipe, 也就是在内存中开辟了一个大小固定的内存缓冲区, 然后两个进程可以往其中读写数据, 但是遵循一个先进先出原则.

        那这个和共享内存有什么区别? 共享内存是不限制进程在哪块位置读和写, 不可避免的会存在覆盖写的问题, 但是管道, 也就是这个队列, 需要遵循队列的特性,

        如果要实现两个进程的自由读写, 那么就需要提供两个队列, 因为队列是单向读取的. 各个进程还需要互斥的访问信道, 不然会出现类似于一个小消息被消费两次的情况

        当管道满了之后, 那么如果继续写的话, 那么就会阻塞, 直到有数据被消费了之后, 那么就会唤醒写进程, 相同, 如果读的时候为空, 那么读进程就会被阻塞, 直到有数据写入.

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

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

相关文章

05-对混合app应用中的元素进行定位

本文介绍对于混合app应用中的元素如何进行定位。 一、app的类型 1)Native App(原生应用) 原生应用是指利用Android、IOS平台官方的开发语言、开发类库、工具等进行开发的app应用,在应用性能和交互体验上应该是最好的。 通俗点来…

【论文精读】RayMVSNet

今天读的是发表在CVPR2022上的无监督MVS文章,作者来自于国防科大。 文章链接:RayMVSNet 项目地址:Github Abstract 作者希望直接优化每个camera ray上的深度值,所以提出这个RayMVSNet来学习1D implicit field的序列预测。使用了…

springboot+vue+mybatis酒店管理系统+PPT+论文+讲解+售后

基于Spring框架的小型宾馆旅客信息管理系统采用B/S结构、java开发语言、以及Mysql数据库等技术。系统主要分为管理员和用户二部分,管理员:首页、个人中心、用户管理、客房类型管理、客房信息管理、客房预订管理、入住登记管理、退房评价管理、系统管理&a…

基于Redis提高查询性能(保持数据一致性)

Redis实战篇 | Kyles Blog (cyborg2077.github.io) 目录 背景 商户查询缓存(根据ID查询) 根据店铺类型查询(List型) 缓存更新策略(保证数据一致性) 案例(利用缓存更新策略) 背景 起初客户端…

2024-06-19,面试官问的问题

文章目录 1、采用minIO完成了图片存储,采用阿里云OSS服务器存储图片这两个功能面试官理解为重复,面试官又问minIO怎么同步到OSS?2、讲一下ThreadLocal?3、为什么用ThreadLocal存数据?4、redis有几种数据结构&#xff1…

Office--加载宏-CS上线

免责声明:本文仅做技术交流与学习... 目录 关于宏上线的格式: 操作流程: 其他office文本的上线格式一样: 关于宏上线的格式: doc宏病毒: 1-生成格式为dotm 只要点启用宏就上线 2-生成格式为()word 97-2003 .doc) 被杀 操作流…

13.1.资源清单的管理工具-helm

目录 一、helm的介绍 1.helm的价值概述 2.helm的关键名词 二、安装部署helm 1.解压安装包并设置全局命令 2.添加命令补全 三、使用helm部署服务管理 1.使用helm创建chart 1.1创建工作目录 1.2.helm创建chart 2.响应式创建名称空间 3.安装chart到名称空间 4.使用hel…

机器人运动学笔记

一、建模 参考资料:https://zhuanlan.zhihu.com/p/137960186 1、三维模型和连杆、关节定义 2、设置z轴 SDH和MDH会不一样,主要的区别在于SDH中坐标系在连杆末端,MDH中坐标系在连杆首端。虽然这里只是给出z轴,但是由于后面原点位…

鸿蒙开发通信与连接:【@ohos.connectedTag (有源标签)】

有源标签 说明: 本模块首批接口从API version 8开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。 导入模块 import connectedTag from ohos.connectedTag;connectedTag.init init(): boolean 初始化有源标签芯片。 需要权限&#…

Python学习笔记14:进阶篇(三)。类的终结篇,类的导入和模块的导入。

前言 这篇文章属于类知识的最后一篇,带一点点其他知识,学习内容来自于Python crash course。 关注我私信发送Python crash course,分享一份中文版PDF。 类的导入 在学习的时候,包括之前,我都是在一个文件中把所有代…

48-2 内网渗透 - 利用Metasploit提权

一、Metasploit提权过程概述 Metasploit是一个开源的安全漏洞检测工具,广泛用于安全和IT专业人士识别、验证和利用安全漏洞,同时也支持专家驱动的安全评估和管理。 提权过程详解 1)生成后门 在Kali Linux上使用msfvenom生成反向连接的后门文件。 # ip 要改成自…

第七节 文本框的默认输入设置

通常我们常见设置一些文本框,默认提示一段信息,在文本框输入值变化值切换实际输入值,那么这时怎么添加情形进行设置呢,请看下面这个案例说明。 第一种,添加文本框不为空,显示为当前输入值 1、添加文本框&…

什么是进程

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在了解进程之前,我们需要知道多任务的概念。多任务,顾名思义,就是指操作系统能够执行多个任务。例如,…

为什么带上符号位计算,仍然可以算出正负数对应的补码

文章目录 🚀前言🚀 为什么要引入原反补码✈️ 利用加法表示减法✈️ 关于数字在计算机中的存储🚀 数学解释 🚀 为什么带上符号位计算,仍然可以算出正负数对应的补码 🚀前言 为应付期末,速成数电…

ROS 机器人运动控制

ROS 机器人运动控制 机器人运动 当我们拿到一台机器人,其配套的程序源码中,通常会有机器人核心节点,这个核心节点既能够驱动机器人的底层硬件,同时向上还会订阅一个速度话题。我们只需要编写一个新的节点(速度控制节点…

(四十二)Vue之路由及其基本使用Vue Router

文章目录 概念基本使用demo几个注意点 上一篇:(四十一)Vuex之模块化与命名空间 概念 在计算机科学和网络领域中,路由(Routing)是指确定数据包在网络中传输的路径和方式的过程。它涉及到根据源地址和目标地…

杂说咋说-关于城市化发展和城市治理的几点建议(浙江借鉴)

杂说咋说-关于城市化发展和城市治理的几点建议(浙江借鉴) 近年来,浙江省坚持一张蓝图绘到底,推动城市化发展和城市治理不断迈上新台阶,全省城市化水平和城市治理能力牢牢居于全国第一方阵。当前,国内外环境…

DFS(一)

问题一(指数级选择) 从1~n这n个整数中任意选取多个,输出所有可能的选择方案。 首先想一下,在现实世界中,我们要如何解决这个问题。 应该是一个一个枚举,即每个数都可以有两个选择(选/不选)。共有种结果。 想一下,如…

JavaSE 面向对象程序设计高级 方法引用 2024详解

在编程中,方法引用(Method Reference)是一种技术,它让你能够直接引用一个现有的函数或方法,而无需通过对象实例来调用。这种方法在函数式编程和高阶函数中非常有用,因为它提供了简洁的方式来传递函数行为&a…

洛谷 P1726:上白泽慧音 ← Tarjan算法

【题目来源】https://www.luogu.com.cn/problem/P1726【题目描述】 在幻想乡,上白泽慧音是以知识渊博闻名的老师。春雪异变导致人间之里的很多道路都被大雪堵塞,使有的学生不能顺利地到达慧音所在的村庄。因此慧音决定换一个能够聚集最多人数的村庄作为新…