根本区别:进程是资源分配的基本单位;线程是程序执行的基本单位
资源开销:每个进程都有独立的资源(代码和数据空间);线程不拥有
系统资源,共享所属进程的资源(代码和数据空间),但是有自己的栈
(在 Java 中为虚拟机栈和本地方法栈)和程序计数器
切换速度:进程切换上下文慢(因为要换数据空间);线程切换上下文
快(因为不用换数据空间)
系统开销:进程的创建和销毁都有很大的系统开销(因为要分配和回收
系统资源);线程的创建和销毁没有很大的系统开销
影响关系:进程崩溃时,其他进程不会受影响(在保护模式下);线程
崩溃时,整个进程都死亡(即本进程中其他线程也死亡)
执行过程:进程可以并发(在操作系统中);线程也可以并发(在同一
个进程中)
进程与线程的区别(前三点是本质,后四点的带来的影响)
包含关系:一个进程有多个线程;多个线程属于一个进程
协程
一个线程可以有多个协程
线程是抢占式,而协程是非抢占式(需要用户释放权限到其他协程)协
程不是操作系统内核控制,而是由程序控制(在用户态执行)
协程的切换不像线程一样消耗资源,所以性能更好,执行效率更高
并发与并行
并发:“假”并行,单核处理器每个时间片执行
不同的进程,宏观上像是并行
并行:“真”并行,需要多核处理器,一个处理
器一个进程,在微观上真正多个进程同时进行
进程与线程的切换
进程的切换:先切换虚拟地址空间,再切换内核栈。切换虚拟地址空间需
要查找页表,所以很慢
线程的切换:只需切换内核栈。不用切换虚拟地址空间(因为进程中的线
程共享地址空间),所以很快
进程之间的通信
管道
1. 特点:半双工(数据只能单向流动);只能在有亲缘关系的进程间使用
(通常指父子进程)
2. 分类:匿名管道(只能用于父子进程之类的有亲缘关系的进程);命名管
道(可以用于任意两个进程的通信)
3. 实质:管道其实就是一个内核缓冲区,先进先出(可看作循环队列),一
个进程在一端写入,另一个进程在另一端读出
消息队列
1. 消息队列就是消息组成的链表,所以解决了管道缓冲区大小有限的问题
2. 消息队列中每个消息的类型都可以不一样,接收的时候也不用按队列次
序,所以解决了管道只能传无格式的字节流的问题
共享内存
1. 共享内存就是多个进程把同一块内存映射到各自的地址空间中
2. 共享内存是效率最高的进程通讯方式
3. 共享内存会一直保持到通信完成,在解除映射时才把内容写回文件
套接字(Socket)
可用于不同机器间的通信,其他通讯机制都是同一台机器中不同进程的通信
信号
信号是一种比较复杂的通信方式,任何时候都可以给任何进程发信号,而不
用知道目标进程的状态(Linux 系统中常用的进程指令就是信号)
信号量
1. 信号量是一个计数器,用于与共享内存配合,解决锁与同步的问题
2. 进程要用共享资源时,先将信号量 -1 。若减完 < 0 说明已被占用,进程
进入阻塞等待;若减完 >= 0 说明未被占用,则该进程使用该资源
3. 进程用完共享资源时,先将信号量 +1。若加完 <= 0 说明有进程在阻塞
等待,则将其唤醒;若加完 > 0 说明没有进程在等待
进程之间的同步(用以辅助进程间的通讯)
临界区
1. 让多线程串行化,使得同一时刻只能有一个线程在访问数据
2. 优点是速度快;缺点是只能用于一个进程内部的线程之间
互斥量
1. 类似于锁,互斥对象只有一个,拥有了互斥对象的线程才能访问共享资源
2. 优点是可以用于不同进程的线程之间;缺点是需要占用更多资源
信号量
1. 用于控制用户数量,允许多个线程在同一时刻访问共享资源,但是要限制
可以同时访问共享资源的线程的数量
2. 互斥量是信号量的一种特殊情况,把信号量的最大资源数设为 1 就变成了
互斥量
3. 优点是适用于 Socket 程序中的线程同步;缺点是不能用于分布式操作系统
(因为必须有公共内存),且不易于管理和控制
线程之间的同步
临界区
一个线程访问共享资源时拥有临界区对象,其他线程若要访问则被挂起,直到
临界区被释放
互斥量
1. 类似于锁,互斥对象只有一个,拥有了互斥对象的线程才能访问共享资源
2. 优点是可以用在不同进程的线程之间;缺点是需要占用更多资源
信号量
1. 用于控制用户数量,允许多个线程在同一时刻访问共享资源,但是要限制
可以同时访问共享资源的线程的数量
2. 互斥量是信号量的一种特殊情况,把信号量的最大资源数设为 1 就变成了
互斥量
3. 优点是适用于 Socket 程序中的线程同步;缺点是不能用于分布式操作系统
(因为必须有公共内存),且不易于管理和控制
事件
1. 一个线程处理完一个任务后主动唤醒另一个线程(通知另一个线程某事件
发生),让另一个线程继续执行任务
2. 优点是可以用于不同进程的线程之间
事件
1. 一个线程处理完一个任务后主动唤醒另一个线程(通知另一个线程某事件
发生),让另一个线程继续执行任务
2. 优点是可以用于不同进程的线程之间
临界区
临界资源:一次只允许一个进程使用的资源
临界区:进程中要访问临界资源的那段程序
死锁产生的条件
1. 互斥:一个资源一次只能一个进程使用
2. 不撒手:进程等待资源而阻塞时,不释放已获得的资源
3. 不能抢:对进程获得的资源不能强行剥夺
4. 循环:多个进程循环等待资源
死锁的解决方案
预防(即针对 4 个产生条件进行解决)
1. 互斥:让资源不互斥
2. 不撒手:让进程运行前一次获取全部资源,但是有时候进程无法知道都需
要哪些资源,而且会降低并发性和资源利用率
3. 不能抢:当进程获取不到某个资源时,就要释放所有已获取的资源。以后
再重新申请(输一次就输光全部)
4. 循环:将所有资源编号排序(紧缺的资源用较大的编号),让进程必须按
顺序获取资源,只有已获得小号的资源才能继续申请大号的资源
避免
动态检测系统中的资源分配情况,判断有没有可能出现死锁,保证可能导致死
锁的“循环”条件不出现
检测
周期性检测资源分配图,从一个节点出发进行深度优先遍历,如果访问到了已
访问过的节点,说明图中存在环,也就是发生了死锁
解除
当出现死锁时,有两种方法进行解除。
第一种是终止进程法。直接终止所有进程;或者一个一个地终止进程直到死锁
被打破。
第二种是资源抢占法。从一个或多个进程中强行剥夺一个或多个资源,从而打
破死锁。
鸵鸟
装鸵鸟,什么也不做,就当没看见死锁。
因为解决死锁问题的代价很高,鸵鸟策略可以得到更高的性能。
大多数操作系统(包括 Unix、Linux 和 Windows)都是用鸵鸟策略。
进程的调度策略
先到先得
1. 非抢占式,谁先请求谁先执行
2. 但是对短作业不公平,明明可以很快执行完,却非要等长作业执行完
短作业优先
1. 非抢占式,估计运行时间最短的作业先执行
2. 对长作业不公平,长作业可能因为一直等短作业而直接饿死,永远轮不到
最短剩余时间优先
1. 抢占式,短作业优先的抢占式版本,按作业的剩余时间进行调度
2. 新作业到达时将其执行时间与正在执行的作业的剩余时间比较。若新进程
所需时间更少,则挂起正在执行的进程并转而去执行新进程;否则新进程等待
时间片轮转
1. 所有就绪的进程排成一个队列,从队首开始,每人执行一个时间片,然后
去队尾
2. 该方法的效率与时间片大小有很大关系,时间片太小就会频繁切换而浪费
时间,时间片太大又无法保证实时性
优先级调度
1. 给每个进程设一个优先级,按优先级进行调度
2. 为了防止低优先级的进程饿死,可以随着时间推移增加等待进程的优先级
进程的状态
获取到了所需的资源
需要新资源,要等
按某种策略被从就绪队列中选中
时间片用完或者有更
高优先级的进程来抢
虚拟内存
1. 虚拟内存就是把物理内存扩大成逻辑内存,让程序看起来好像可以使用很多
内存
2. 进程和资源都只有一部分页面真的加载进了内存,其余的页面其实存在磁盘
里
3. 虚拟内存使得内存可以同时加载更多的进程,甚至能加载比内存大的进程
4. 虚拟内存使得内存“看起来”变大了
用户态与内核态
用户态与内核态是操作系统的两种运行状态
内核态可以访问任何数据和资源(包括硬件),
且 CPU 不会被抢占
用户态只能访问部分内存和用户数据,且 CPU 可
以被其他程序抢占
操作系统分为用户态与内核态是为了防止用户程
序做危险操作(如设置时钟、清理内存等)
评论5
最新资源