第三章 多进程——操作系统最核心的视图

本文基于《操作系统原理,实现与实践》探讨CPU的多进程管理。进程是程序的抽象,用于并发执行,通过PCB进行控制。进程状态包括运行、就绪和阻塞,操作系统使用调度算法进行切换。进程间通过内存管理和通信合作,如信号量机制解决同步问题。实践项目涉及打印日志进程的管理。
摘要由CSDN通过智能技术生成

本文内容是自己整理的,基于李志军和刘宏伟老师的《操作系统原理,实现与实践》,用于快速回忆相关内容。

本章是总述章节,通过本章可以让你大概的,模糊的了解计算机CPU多进程的概念。具体的,某一块的详细内容将在后续章节中,由本人给大家娓娓道来。

3.1 如何使用CPU

        3.1.1 CPU工作机理与使用CPU的直观想法

        3.1.2 问题的引出与并发

3.2 进程概念与多进程视图

        3.2.1 进程与程序

首先要明白的是,进程是对程序的一层抽象,是为了并发而提出来的。但进程与程序不同的是,它是指运行起来的程序。具体来说的话:进程就是 程序以及反映进程执行的信息(这些信息保存在一些数据结构中,这些数据结构构成了一个unit,称为PCB,process control block)。

PCB中存储着进程的基本信息,是操作系统知晓进程的唯一标志。就像你的身份证上存储的所有信息,标识了你这个人一样,是管控人员了解你的唯一途径。为了标识不同的进程,CPU会给每一个进程分配一个PID process identity document,如同你的身份证号码,可以供给需要的时候来查询。

        3.2.2 CPU管理与多进程视图

此时,我们依靠着进程这一概念,对CPU管理程序进行更为详细的描述:为操作系统启动多个进程,并能在多个进程之间调度/切换。

3.3 多进程引起的基本问题

        3.3.1 多个进程的组织与进程状态

操作系统要实现多进程的有序执行,首先就要解决如何组织这多个进程的问题。分析这多个进程之间的关系,如同学生排队打饭,等待着CPU的调度。那么显而易见的我们可以准备队列来组织进程。

我们知道多个进程在执行的时候,有的遇到I/O需要等待结果,有的需要正在执行,还有的已经万事俱备就差CPU来进行调度。我们大体的,简单分明的把多个进程,它们的状态划分为三种:运行态——占用CPU,正在执行;就绪态——具有所有可执行条件的进程,只需CPU来调度;阻塞态——因为缺乏一些东西导致即使CPU来调度也无法执行。

        3.3.2 多个进程的切换与调度

前面基本介绍了CPU为了并发,从而引出进程来对程序进行一层抽象,然后为了方便管理,便使用了队列来组织进程。这一小节我们主要解决两个问题并发进程如何切换?以及到了该切换的时候,切换那些进程来执行?

首先,第一个问题:并发进程如何进行切换: 简单来讲,操作系统把相关切换内容封装在一个函数 schedule() 中。在这个函数中:1.我们先通过调度来找到要切换到哪个进程(B进程),也就是找到那个进程的PCB;2.然后把当前进程的执行现场保存在当前进程(A进程)的PCB中;3.最后,取出我们B进程PCB中的内容,覆盖到当前的执行现场,也就是把B中PCB内容替换掉寄存器里的内容。整个切换过程大体来看就是上述的三个步骤,但当我们具体看的时候,或者说自己去实现的时候,还是有着很多东西需要我们去了解。详细内容将在第五章 进程同步——让多个进程的推进合理有序中呈现。

其次,第二个问题:多个并发进程之间,该选择谁来呢? 调度问题是一个两难问题,它没有最终答案,只有相对来说比较适合的答案。就像人生的意义,不同的人有着不同的理解,手里有很多钱的人和手里没钱的人对于各种生活必须条件的的优先级是不同的。我们要做的是具体问题具体分析,选择一个合适的调度算法。详细内容将在第五章 进程同步——让多个进程的推进合理有序中呈现。

        3.3.3 进程间的影响分离

前面我们讲了如何让CPU组织多个进程,多个进程之间的切换和调度等问题。这一小节我们介绍一下进程之间的另一个问题:进程间数据上的使用问题。

假设现在我们有两个进程:A和B。进程A调用指令修改了内存地址100处的数据,而100处的数据恰好是B中核心的数据,这个时候就会导致进程B出现错误。前面我们虽然在切换的时候保存了相关的执行现场到PCB中,但保存在内存,外存上的数据是不会发生改变的。这个时候我们就需要对进程之间进行地址隔离策略,即让A进程不能通过代码上的地址来直接操作物理内存地址,而是通过一张映射表来对应到一个真实的物理地址。操作系统给每一个进程分配一段只属于该进程,互相不重叠的区域,这样A进程不论如何访问都不会因为误操作而影响到其他进程了。相关内存管理部分将在第六章 内存管理——给程序执行提供一个舞台中详细来讲

        3.3.4 进程间的通信与合作

这一节讲述:进程间的合作问题

多个进程为了完成操作者想要的功能,往往需要合作配合。比如:剪贴板,我们从网页上复制一段信息,然后保存在Word文档之中。

进程之间的通信实现并不困难,比如读写同一个数据库,同一个文件,一段共享内存等。

进程间的通信并不困难,但合作却是麻烦重重:假如相关的合作机制并不合理,就有丢失数据的风险,比如购买一张火车票,在A进程还未完成付款操作时,B进程也进来购买,这时结束的是A和B都获得了这张火车票。这显然是不可以接受的事情,为了理解相关合作内容,我们先抽象出一个基本的,五脏俱全的一个合作模型:生产者——消费者 模型。在这个模型里,生产者负责往共享缓冲区中写入数据,消费者负责从共享缓冲区中读出数据。共同享有一个信号counter来表示缓存区中数据的大小,当数据量充满了整个缓冲区的时候,生产者就会停止生产。同样的,当缓冲区数据量为空的时候,消费者就会停止消费吗,等待生产者的生产。但是我们知道CPU是并发的执行的,所以进程执行相关代码时,对于conunter的修改可能就会发生错误。描述这个问题的时候我们首先需要知道,counter=counter+1在底层执行时,是先用寄存器复制原有的值P.register=counter,然后再对寄存器进行修改P.register = P.register+1,最后返回给counter。此时,两个进程同时修改counter,通过并发,最后执行counter=P.register,假设counter原先值为5,那么修改后结果为6,这显然是不对的。为了解决这种问题,关键就是要让它们对于信号的修改一次性完成,中间不受其他程序的干扰,这就是临界区的概念。详细内容将在第五章 进程同步——让多个进程的推进合理有序中细说。

3.4 实践项目3:打印日志进程

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值