2023-07-11
计算机基础
00
请注意,本文编写于 509 天前,最后修改于 411 天前,其中某些信息可能已经过时。

目录

操作系统简介
操作系统的演进
操作系统基本功能
进程与线程
进程实体
进程与线程的区别
进程的五状态模型
进程间的通信
没有进程通信的问题
进程同步的原则
进程间同步的方法
线程同步
fork创建进程
Linux进程管理
进程的类型
进程的标记
Linux进程相关命令
进程调度
死锁
死锁产生的原因
产生死锁的必要条件
预防死锁的方法:
解决死锁-银行家算法

与前一篇《计算机组成原理》一样,本不想过多研究,学习的过程中却发现一些有意思的算法,经典问题的解决方案,对设计和编写大型项目有借鉴意义。本文将讲解进程的实体和五种状态,进程线程同步方法调度、管理、死锁、linux进程相关、命令行等问题。

操作系统简介

  • 操作系统是管理计算机硬件和软件资源的计算机程序
  • 如何管理? 通过管理配置内存、决定资源供需顺序、控制输入输出设备等。
  • 操作系统提供用户和系统交互的操作界面
  • 不同设备上,操作系统课向用户呈现多种操作手段
  • 终极定义: 管理硬件、提供用户交互的软件系统

为什么需要操作系统

  • 我们不可能直接操作计算机硬件
  • 设备种类繁多复杂,需要统一界面
  • 操作系统的简易性使得更多人能够使用计算机

操作系统的演进

image.png

多道程序设计

  • 早期批处理系统只能一次处理一个任务
  • 多道程序设计使得批处理系统可以一次处理多个任务
  • 多道程序设计是指在计算机内存中同时存放多个程序
  • 多道程序在计算机的管理程序之下相互穿插运行

操作系统基本功能

  1. 操作系统实现了对计算机资源的抽象
    • 计算机资源是指 处理器资源、IO设备资源、存储器资源、文件资源
    • 用户无需面向硬件接口编程
    • IO设备管理软件,提供读写接口
    • 文件管理软件,提高难过操作文件接口
  2. 操作系统提供了用户与计算机之间的接口

操作系统相关概念

  • 并发性 逻辑上同时发生,对于单核CPU不能实现物理时间上的并行, 与并行的异同
  • 共享性
    • 共享性表现为操作系统中的资源可供多个并发的程序共同使用
    • 资源共享可以分为两种形式互斥共享形式同时访问形式
    • 互斥共享
      • 当资源被程序A占用时,其他想使用的话只能等待
      • 只有进程A使用完以后,其他进程才可以使用该资源
      • 例子: 打印机
    • 同时访问形式
      • 某种资源在一段时间内并发地被多个程序访问
      • 这种“同时”是宏观的,从宏观去看该资源可以被同时访问
      • 比如往磁盘写数据, 有两个文件同时进行, 由于悬臂只有一个,不可能真正的同时进行,但写数据速度很快,宏观上看是同时写入
  • 虚拟性
    • 把一个物理实体转变为若干个逻辑实体
    • 物理实体是真实存在的,逻辑实体是虚拟的
    • 虚拟的技术主要有时分复用技术和空分复用技术
    • 时分复用技术
      • 资源在时间上进行复用,不同程序并发使用
      • 多道程序分时使用计算机的硬件资源,提高资源的利用率
      • image.png
    • 空分复用技术
      • 空分复用技术用来实现虚拟磁盘、虚拟内存等
      • 提高资源的利用率,提升编程效率
      • image.png
  • 异步性
    • 在多道程序环境下,允许多个进程并发执行
    • 进程在使用资源时可能需要等待或放弃
    • 进程的执行并不是一气呵成的,而是以走走停停的形式推进
    • image.png

进程与线程

为什没需要进程

  • 没有配置OS之前,资源属于当前运行的程序
  • 配置OS之后,引入多道程序设计的概念
  • 合理的隔离资源、运行环境,提升资源利用率

进程作用

  • 进程是系统进行资源分配和调度的基本单位
  • 进程作为程序独立运行的载体保障程序正常执行
  • 进程的存在使得操作系统资源的利用率大幅提升

进程实体

进程中包含以下内容

  • 标识符
  • 状态
    • 标记程序的进程状态
  • 程序计数器
    • 进程被执行的下一个指令的地址
  • 内存指针
    • 程序代码、进程数据相关指针
  • 上下文数据
    • 程序执行时处理器存储的数据
  • IO状态信息
    • 被进程IO操作所占用的文件列表
  • 记账信息
    • 使用处理器时间、时钟数总和等

进程控制块PCB

  • 用于描述课控制程序运行的通用数据结构
  • 记录进程当前状态和控制进程运行的全部信息
  • PCB使得进程能够独立运行的基本单位
  • PCB是操作系统进行调度经常会被读取的信息
  • PCB是常驻内存的,存放在系统专门开辟的PCB区域内

进程与线程的区别

- 进程Process 线程Thread
基本关系 线程不能独立存在,它由进程启动和管理的
一个进程包含多个线程
进程通过多线程提高效率
一个线程的崩溃会导致整个进程的崩溃
资源 是操作系统进行资源的基本单位 不拥有资源,但多个线程可以共享进程中的资源
调度 是操作系统独立调度的基本单位 是操作系统独立调度的最小单位
系统开销 开销大 开销小
通信 进程间通过IPC通信 读写同一进程数据的通信进行通信
其他 进程间资源相互隔离
当一个进程关闭之后操作系统会回收系统所占用的内存

进程的五状态模型

image.png

  • 就绪状态
    • 当进程被分配到除CPU以外所有必要的资源后
    • 只要再获得CPU的使用权,就可以立即运行
    • 就绪队列 在一个系统中多个处于就绪状态的进程通常排成一个队列
  • 执行状态
    • 进程获得CPU,其程序正在执行称为执行状态
    • 在单处理机中,在某个时刻只能有一个进程是处于执行状态
  • 阻塞状态
    • 进程因某种原因如:其他设备未就绪而无法继续执行
    • 从而放弃CPU的状态称为阻塞状态
  • 创建状态
    • 1.分配PCB
    • 2.插入就绪队列
    • 创建进程时拥有PCB但其他资源为就绪的状态称为创建状态
    • 操作系统提供fork函数接口创建进程
  • 终止状态
    • 1.系统清理 2.PCB归还
    • 进程由系统清理或者归还PCB的状态称为终止状态

进程间的通信

没有进程通信的问题

为什么需要进程间的同步?先来了解一个背景--生产者-消费者问题

  • 生产者消费者问题
  • 有一群生产者进程在生产产品,并将这些产品提供给消费者进程进行消费,生产者进程和消费者进程可以并发执行,在两者之间设置了一个具有n可缓冲区的缓冲池,生产者进程需要将所生产的产品放到一个缓冲区中,消费者进程可以从缓冲区取走产品消费。 生产消费问题.png
  • 除此之外,没有进程间同步,还可能带来另一个更严重问题--死锁 在了解死锁前先来看一个问题 哲学家进餐问题 jincan.png 临界资源
  • 一些虽作为共享资源却又无法同时被多个线程共同访问的共享资源。当有进程在使用临界资源时,其他进程必须依据操作系统的同步机制等待占用进程释放该共享资源才可以重新竞争使用该资源。

image.png

进程同步的原则

  • 空闲让进:资源无占用,允许使用
  • 忙则等待:资源有占用,请求进程等待
  • 有限等待:保证有限等待时间能够使用资源
  • 让权等待:等待时,进程需要让出CPU

进程间同步的方法

  • 共享存储

    • 共享存储允许不相关的进程访问同一片物理内存
    • 共享内存是两个进程之间共享和传递数据最快的方式
    • 共享内存未提供同步机制,需要借助其他机制管理访问
  • Unix域套接字

    • 套接字(socket)原是网络通信中使用的术语
    • Unix系统提供的域套接字提供了网络套接字类似的功能
      • 提供了单机简单可靠的进程通信同步服务
      • 只能在单机使用,不能跨机器使用
    • 域套接字是一种高级的进程间通信的方法
  • 消息队列

  • 信号量

线程同步

当多个线程并发使用进程资源时,也会出现生产者消费者问题和哲学家问题,故进程内多线程也需要同步。

线程同步方法

  1. 互斥量
    • image.png
    • 原子性是指一系列操作不可被中断的特性
    • 这一系列操作要么全部执行完成,要么全部没有执行
    • 不存在部分执行部分未执行的情况
    • 使用加锁、解锁两个状态可以保证资源访问的串行
    • 示例代码
  • 自旋锁
    • 自旋锁也是一种多线程同步的变量
    • 使用自旋锁的线程会反复检查锁变量是否可用
    • 自旋锁不会让出CPU,是一种忙等待状态(与互斥量的区别)
    • 自旋锁避免了进程或线程上下文切换的开销
    • 操作系统内部很多地方使用的是自旋锁
    • 自旋锁不适合在单核CPU使用
  • 读写锁
    • 读写锁是一种特殊的自旋锁
    • 允许多个读者同时访问资源以提高读性能
    • 对于写操作则是互斥的
  • 条件变量
    • 条件变量是一种相对复杂的线程同步方法
    • 条件变量允许线程睡眠,直到满足某种条件
    • 当满足条件时,可以向该线程信号,通知唤醒

总结

同步方法描述
互斥锁最简单的一种线程同步方法,会阻塞线程
自旋锁避免切换的一种线程同步方法,属于忙等待,不适合单核CPU
读写锁一种特殊的自旋锁,为 “读多写少” 的资源设计的线程同步方法,可以显著提高性能
条件变量睡眠唤醒相对复杂的一种线程同步方法,有更灵活的使用场景

fork创建进程

  • fork系统调用是用于创建进程的
  • fork创建的进程初始化状态与父进程一样
  • 系统会为fork的进程分配新的资源
  • fork系统调用无参数
  • fork会返回两次,分别返回子进程id和0
    • 返回子进程id的是父进程,返回0的是子进程

补充资料: 线程与进程同步方法 C++示例代码

Linux进程管理

进程的类型

  • 前台进程
    • 前台进程就是具有终端,可以和用户交互的进程
  • 后台进程 将需要执行的命令以“&”符号结束
    • 与前台进程相对,没有占用终端的就是后台进程
    • 后台程序基本上不和用户交互,优先级比前台进程低
  • 守护进程 进程名字以“d”结尾的一般都是守护进程
    • 守护(daemon)进程是特殊的后台进程
    • 很多守护进程在系统引导的时候启动,一直运行直到系统关闭
    • Linux有很多典型的守护进程 crond sshd httpd mysqld
sh
python3 running_process.py & # 此时终端返回进程id 例: [1] 61888 # 终止 kill -9 [进程id] # 或者 kill -9 %1 # 关闭该终端窗口创建的最近一个后台进程 # 虽然是后台进程如果有输出还会在终端打印 # 丢丢弃输出 python3 running_process.py 2>&1 > dev/null &

进程的标记

  • 进程ID
    • 是进程的唯一标记,每个进程拥有不同的ID
    • 进程ID表现为一个非负整数,最大值由操作系统限定
    • top 命令查看所有的进程
    • 父子进程, 父进程使用fork接口创建子进程
    • pstree打印进程间关系
    • ID为0的进程为idle进程,是系统创建的第一个进程
    • ID为1的进程为init进程,是0号进程的子进程,完成系统初始化
    • Init进程是所有用户进程的祖先进程
  • 进程的状态标记
状态符号状态说明
R(TASK_RUNNING),进程正处于运行状态
S(TASK_INTERRUPTIBLE),进程正处于睡眠状态
D(TASK_UNINTERRUPTIBLE),进程正在处于IO等待的睡眠状态
T(TASK_STOPPED),进程正处于暂停状态
Z(TASK_DEAD or EXIT_ZOMBIE),进程正处于退出状态,或僵尸进程

ps -aux | grep [进程ID / 进程名称] 查看进程状态

Linux进程相关命令

  • ps
  • top
  • kill 给进程传递信号, -9 无条件退出
sh
ps # 列出当前终端shell所运行的进程 ps -aux # aux打印进程的详细信息 ps -u root # 指定用户所运行的进程 ps aux | grep [进程ID/进程名称] # 查询进程 ps -ef --forest # 查看进程树 (会打印父子进程关系) ps -aux --sort=-pcpu # 查看进程按CPU使用频率排序 ps -aux --sort=-pmem # 查看进程按内存使用排序

进程调度

进程调度是指计算机通过决策决定哪个就绪进程可以获得CPU使用权

  • 保留旧进程的运行信息,请出旧进程(收拾包袱)
  • 选择新进程,准备运行环境并分配CPU(新进驻)

进程调度也被称为作业管理

进程调度有哪些机制?

  • 就绪队列的排队机制
    • 将就绪进程按照一定的方式排成队列,以便调度程序可以最快找到就绪进程
  • 选择运行进程的委派机制
    • 调度程序以一定的策略选择就绪进程,将CPU资源分配给它
  • 新老进程的上下文切换机制
    • 保存当前进程的上下文信息,装入被委派执行进程的运行上下文

进程调度时,如果老进程还没执行完怎么办?

  • 非抢占式调度
    • 处理器一旦分配给某个进程,就让该进程一直使用下去
    • 调度程序不以任何原因抢占正在被使用的处理器
    • 直到进程完成工作或因为IO阻塞才会让出处理器
  • 抢占式调度
    • 允许调度程序以一定的策略暂停当前运行的进程
    • 保存好旧进程的上下文信息,分配处理器给新进程
抢占式调度非抢占式调度
系统开销频繁切换,开销大切换次数少,开销小
公平性相对公平不公平
应用通用系统专用系统

进程的调度算法

描述优点缺点
先来先服务调度算法高效长作业进程阻塞
短进程优先调度算法调度程序优先选择就绪队列中估计运行时间最短的进程高效不利于长作业进程的执行
高优先权优先调度算法进程附带优先权,调度程序优先选择权重高的进程使得紧迫的任务可以优先处理-
时间片轮转调度算法按先来先服务的原则排列就绪进程
每次从队列头部取出待执行进程,分配一个时间片执行
相对公平不能保证及时响应用户

死锁

image.png

所谓死锁是值多个进程在运行过程中因争抢资源而造成的一种僵局,当线程处于这种僵持的状态时,无外力的作用,他们将无法再向前推进。

系统中的资源可以分为两类

  1. 可剥夺资源,是指某进程在获得这类资源后,该资源可以被其他进程或系统剥夺,CPU和主存均是可剥夺性资源;
  2. 不可剥夺资源,当系统把这类资源分配给某进程后,再不能强行收回,只能在进程用完之后自动释放,如磁带、打印机等。

死锁产生的原因

  • 竞争不可剥夺资源(如打印机),或竞争临时资源(硬件中断、信号、消息、缓冲区内的消息等)
  • 进程调度顺序不当

调度顺序不当 如何理解?

image.png

  • 比如有A、B 两个进程 和 打印机、传真机两个IO设备
  • A需要先使用打印机后使用传真机,B先使用传真机后使用打印机, 如果两个进程都是执行完才释放IO资源,那么就会造成死锁,
  • 假设让A先执行,执行完了再调度B (反之也行), 就不会造成死锁

产生死锁的必要条件

  1. 互斥条件:进程要求对所分配的资源进行排它性控制,即在一段时间内某资源仅为一进程所占用
  2. 请求和保持条件:当进程因请求资源而阻塞时,对已获得的资源保持不放
  3. 不剥夺条件:进程已获得的资源在未使用完之前,不能剥夺,只能在使用完时由自己释放
  4. 环路等待条件:在发生死锁时,必然存在一个进程——资源的环形链

预防死锁的方法:

本质上破坏死锁的四个必要条件之一

  1. 资源一次性分配:一次性分配所有资源,这样就不会再有请求了(破坏请求条件)
    • 破坏请求保持条件
  2. 先释放已占有的资源才能请求其他资源
    • 破坏请求保持条件
  3. 如果申请的资源得不到那么释放已占有的资源
    • 破坏不可剥夺条件
  4. 资源有序分配法:系统给每类资源赋予一个编号,每一个进程按编号递增的顺序请求资源,释放则相反
    • 比如 有a、b、c、d四个资源, 进程A需要acd资源,那么a申请了acd资源,即便有资源未使用也不给其他进程分配
    • 破坏环路等待条件

解决死锁-银行家算法

以银行借贷系统分配策略为基础的算法

  1. 客户申请的贷款是有限的,每次申请需声明最大资金量
  2. 银行家在能够满足贷款时,都应该给用户贷款
  3. 客户在使用贷款后,能够及时归还贷款

银行家算法.png

本文作者:郭敬文

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!