进程的概念
1. 进程的概念
指一个应用程序运行了起来, 进程是操作系统分配资源的一个最小单位
2. 进程的结构
控制块(PCB): 存放着进程的唯一ID 如果运行了多个微信进程 他们的ID也是唯一的
数据块: 存放着进程的原始数据和中间数据
程序块: 多个进程共享 存放在文本区域 这个的多个进程是指如果开启了多个微信程序 则多个微信程序共享程序块
线程的概念
1. 线程的概念
操作系统最小调度单位, 不能独立运行 被包含于进程, 一个进程可以有一个或多个进程
也被叫做轻量级进程 但是轻量级进程多用于内核级进程 而用户级线程成为线程
2. 内核级线程
线程的控制块在操作系统的内核空间里 被称为内核级线程 但是线程的数据块和程序块还依然在用户空间
优点:
实现了真正意义上的线程并行
不需要运行时系统的参与
缺点:
正因为数据块和程序块在用户空间 所以频繁的切换会导致内核开销大
3. 用户级线程
线程的控制快在操作系统的用户控件里 被称为用户级线程 不依赖于操作系统 调度依赖于用户程序 在操作系统的视角里其实感觉不到用户级线程的存在
优点:
线程位于用户控件(不需要模式切换)
独立于操作系统(线程可以在不支持他们的操作系统上运行)
运行时系统(run time system)可以切换用户空间中的本地阻塞线程(例如:等待另一个线程完成)
缺点:
系统调度中, 对一个线程的阻塞将会导致整个进程的阻塞
非真正意义的线程并行(一个进程安排在单个cpu上)
不存在时钟中断
进程与线程的区别
1. 进程是操作系统分配资源的最小单位 线程是操作系统最小调度单位
2. 一个线程只属于一个进程 但一个进程可以包括多个线程
3. 线程没有独立的内存地址 它包括在进程的地址空间里
4. 线程的开销比进程更小
进程运行
五种基本状态
- 创建: 创建好一个进程
- 就绪:进程做好了执行的准备 就差分配处理机
- 运行:该进程正在执行
- 阻塞:等待某事件发生才能执行,如等待I/O完成
- 终止:进程被关闭
进程控制
-
什么是进程控制**
即os对进程实现有效的管理 比如进程的创建、进程切换等动作
os 通过 原语 操作来实现进程控制
-
什么是原语
由若干条指令组成 具有原子性
-
原语的特点
- 原子操作 要么全部执行 要么全部失败 执行过程不会被终止
- 在管态/系统态/内核态下执行,常驻内存
- 是内核三大支撑功能之一(中断机制,时钟管理,原语操作)
进程是怎么运行的
- 创建原语:create
- 阻塞原语:block
- 唤醒原语:wakeup
- 撤销原语:destroy
- 挂起原语:suspend
- 激活原语:active
处理机
- 什么是处理机
- 根据一定的算法和原则将处理机资源进行重新分配的过程
- 前提:作业/进程数目一定远远大于处理机数目
- 目的:提高资源利用率 减少处理机空闲时间
- 处理机调度:调度的层次
- 高级调度/作业调度
- 把后备作业调入内存
- 只调入一次 调出一次
- 中级调度/内存调度
- 将进程调至外存 条件合适再调入内存
- 在内存 外存对换区进行进程对换
- 低级调度/进程调度
- 从就绪队列选取进程分配给处理机
- 最基本的调度 频率非常高(相当于一个时间片完成)
- 高级调度/作业调度
调度算法
先来先服务
- 算法内容:调度作业/就绪队列中最先入队者,等待操作完成和阻塞
- 算法原则:按作业/进程到达顺序服务
- 调度方式:非抢占调度
- 适用场景:作业/进程调度
- 优缺点
- 有利于CPU繁忙型作业 充分利用CPU资源
- 不利于I/O繁忙型作业 操作耗时 其他饥饿
短作业优先
- 算法内容:所需服务时间最短的作业/进程优先服务
- 算法原则:追求最小的平均周转时间
- 调度方式:非抢占式服务(除了服务时间最短 还有另一种方式-最短剩余时间优先)
- 适用场景:作业/进程调度
- 优缺点
- 平均等待/调度时间最少
- 长作业会增加或者饥饿
- 估计时间不准确 不能保证紧急任务及时处理
高响应比优先调度
- 算法内容:结合先来先服务&短作业优先,综合考虑等待时间和服务时间计算响应比 高的响应比优先调度
- 算法原则:综合考虑作业/进程的等待时间和服务时间
- 调度方式:非抢占调度
- 适用场景:作业/进程调度
- 响应比计算
- (等待时间 + 服务时间) / 服务时间
- 当前进程完成或者阻塞时重新计算所有的进程响应比
优先级调度
- 算法内容:又叫优先权调度,按作业/进程的优先级(紧迫程度)进行调度
- 算法原则:优先级最高的作业/进程先调度
- 调度方式:抢占(高优先级立即执行)/非抢占(高优先级等待当前进程让出后执行)
- 适用场景:作业/进程调度
- 优先级设置原则
- 静态/动态优先级
- 系统 > 用户 / 交互型 > 非交互型 / I/O型 > 计算型
- 低优先级进程可能会饥饿
时间片轮转调度
- 算法内容:按进程到达就绪队列的顺序,轮流分配一个时间片去执行,时间用完则剥夺
- 算法原则:公平、轮流为每个进程服务,进程在一定时间内都能得到响应
- 调度方式:抢占式 由时钟中断确定时间
- 适用场景:进程调度
- 优缺点
- 公平,响应快,适用于分时系统
- 时间片决定因素:系统响应时间、就绪队列进程数量、系统处理能力
- 时间片太大,相当于 先来先服务 / 太小 处理机切换频繁 开销增大
多级反馈队列调度
- 算法内容
- 设置多个按优先级排序的就绪队列
- 优先级从高到低 时间片从小到大
- 新进程采用队列降级法 (1. 进入第一级队列 按先来后到分时间片 2. 没有执行完,移动到第二级)
- 前面队列不为空 不执行后续队列进程
- 算法原则:集中前几种算法的优点
- 调度方式:抢占式
- 适用场景:进程调度
- 优缺点
- 对各类型相对公平 可以快速响应
- 也实现了短作业优先
- 周转时间短
- 在前几个队列部分执行
进程通信
共享内存
- 共享内存,指两个或多个进程共享一个给定的存储区
- 共享内存是最快的一种进程通信方式,因为进程是直接对内存进行存取
- 因为多个进程可以同时操作 所以需要进行同步
- 信号量 + 共享内存通常结合在一起使用
管道通信
-
无名管道
-
半双工 具有固定的写端以及读端
-
管道就是一个 队列 是先进先出
-
无名管道只能用于具有亲属关系的进程之间的通信
-
管道其实可以看成一个特殊的文件, 对于他的读写也可以使用 read()/write() 但是管道不属于文件系统,他是用于内存中
-
当一个管道建立时,会创建两个文件文件描述符,要关闭管道只需将这两 个文件描述符关闭即可
Int pipe(int fd[2]);
-
-
有名管道(fifo)
-
有名管道可以用于无关的进程之间通信
-
有名管道有路径名与之相关联,她以一种特殊设备文件形式存在于文件系统中
Int mkfifo(const char* pathname, mode_t mode);
-
消息队列
信号量
- 什么是信号量
- 信号的数量
- 举例:好比一个停车场,里面很多的停车位,停车位是任何车都可以停的,所以可以看成共享资源,那停车位满了,外面肯定就要排队
- P/V 操作
- P操作:wait原语,进程等待
- V操作:signal原语,唤醒等待进程
- 信号量的工作机制
- 由一个 剩余资源数量 & 进程等待队列 实现的结构体
- 如果有一个进程在执行 则剩余资源数量-1
- 如果剩余资源数量为负数,则让当前申请资源的进程进入等待队列并处于阻塞状态
- 如果一个进程执行完毕,则剩余资源数量+1,并且从等待队列唤醒一个进程
进程同步
- 什么是进程同步
- 协调进程间的 相互制约关系, 使他们按照预期的方式执行的过程
- 两种相互制约形式
- 互斥: 进程排他性访问共享资源
- 同步:进程间的合作,比如管道通信
- 互斥的实现
- 临界区:比如打印机、音频设备等 通过对多个进程进程串行化来访问公共资源或一段代码 在任意时刻只允许一个进程访问 一个进程成功访问后就会加锁 直到释放锁 也唤醒其他的阻塞进程
- 互斥对象:互斥对象和临界区很像,采用互斥对象机制,只有拥有互斥对象的进程才有访问公共资源的权限。因为互斥对象只有一个,所以能保证公共资源不会同时被多个进程同时访 问。当前拥有互斥对象的进程处理完任务后必须将进程交出,以便其他进程访问该资源
- 同步的实现
- 信号量:上面已经介绍,在此不多赘述
- 事件对象:通过通知操作的方式来保持进程的同步,还可以方便实现对多个进程的优先级 比较的操作