现代操作系统读书笔记--第二章 进程与线程

进程:对正在运行程序的一个抽象。
2.1 进程
1.伪进程、多处理系统

2.1.1  进程模型
1.顺序进程、虚拟CPU
2.多道程序设计(CPU在进程之间快速切换)
3.由于CPU在各进程之间来回切换,所以每个进程执行其运算的速度是不确定的
4.关键思想:一个进程是某种类型的一个活动,它有程序、输入、输出以及状态,而程序是用适当形式描述的算法。两者区别很微妙。
5.如果一个程序运行了两次,则算作两个进程。

2.1.2 进程的创建
1.导致进程创建的事件:(1)系统初始化 (2)正在运行的程序执行了创建进程的系统调用 (3) 用户请求创建一个进程 (4) 一个批处理作业的初始化
2.守护进程:在大多数时间休眠的进程,如电子邮件接收。
3. UNIX ps列出进程,fork创建进程
4.进程创建之后,父进程和子进程有各自不同的地址空间。
5.写时复制共享,可写的内存是不能被共享的

2.1.3 进程的终止
1.导致进程终止的条件:(1) 正常退出(exit) (2)出错退出 (3)严重错误 (4)被其他进程杀死(kill)

2.1.4 进程的层次结构
1.UNIX中,进程和它的所有子进程以及后裔共同组成一个进程组
2.UNIX 整个系统中,所有进程都属于以init为根的一棵树
3.windows 令牌(句柄)

2.1.5 进程的状态
1.cat 连接文件并输出  grep 选出包含特定单词的行
2.管道:举例:ls -a | grep mysql
说明:就是把前一个命令的结果当成后一个命令的输入。结合本例就是先显示所有的文件,然后再用grep命令在ls的结果中查找包含mysql的文件。
3.进程的三种状态:(1)运行态 (2)就绪态 (3)阻塞态
4.进程调度程序:决定应当运行哪个程序、何时运行以及运行时间。
2.1.6 进程的实现
1.进程表、表项(进程控制块)
2.中断向量:包含中断程序的入口地址
2.1.7 多道程序设计模式
1.严格地说,如果进程用于计算的平均时间是进程在内存中停留时间的20%,且内存中同时有五个进程,则CPU将一直满负载运行。假设这五个进程不会同时等待I/O。
2.概率模型,假设一个进程等待IO操作的概率为p,那么CPU利用率=1-p(n次方),n为多道程序设计的道数
2.2 线程
1.传统操作系统中,每个进程有一个地址空间和一个控制线程,事实上,经常存在同一个地址空间中准并行多个控制线程,这些线程就像分离的进程
2.2.1 线程的使用
1.需要多线程的理由: (1) 程序设计模型变得简单,因为多线程共享地址空间而多进程具有不同地址空间 (2)线程比进程更轻量级,所以他们比进程更容易创建和撤销。 (3) 存在大量计算和IO处理,拥有多个线程允许这些活动彼此重叠进行。  CPU密集型:一些进程绝大多数时间在计算上  I/O密集型:有一些进程则在input 和output上花费了大多时间  (4) 真正的并行有了实现的可能
2.万维网服务器: 高速缓存、分派程序、工作线程
3. 有限状态机

2.2.2 经典的线程模型
1.进程模型基于的概念:资源管理和执行
2.进程用于把资源集中到一起,而线程则是在CPU上被调度执行的实体
3.线程模型增加的内容:即在同一个进程环境中,允许彼此之间有较大独立性的多个线程执行。
4. 线程有时被称为轻量级进程。

5.线程之间是没有保护的,因为一个进程总是由某个用户所拥有,该用户创建多个线程是为了让它们之间合作而不是波次间争斗。

6.和传统进程一样,线程可以处于若干种状态中的任何一个:运行、阻塞、就绪或终止
7.每个线程有其自己的堆栈,供各个被调用但是还没有从中返回的过程使用,通常每个线程会调用不同的过程。

8. thread_creat(创建新线程)、thread_exit(推出线程)、thread_join(等待特定线程退出)、thread_yield(允许线程自动放弃CPU)
9.多线程的缺点:设计复杂;和线程共享许多数据结构事实有关。

2.2.3 POSIX线程
1.pthread:IEEE定义的线程包

2.2.4 在用户空间中实现线程
1.优点:用户级线程包可以在不支持线程的操作系统上实现
2.运行时系统是一个管理线程的过程的集合
3.用户线程包的优点:线程切换比陷入内核要快一个数量级;保存线程状态和调度程序都只是本地过程;允许每个进程有自己制定的调度算法;具有较好的可扩展性。
4.用户线程包的问题:如何实现阻塞系统调用(如果调用会阻塞,就提前通知,通过select系统调用实现,包装器实现检查的代码)缺页中断问题;如果一个线程开始,那么该进程中的其他线程就不能运行;程序员通常在经常发生线程阻塞的应用中才希望使用多个线程。
5.上下文切换:有时也称做进程切换或任务切换,是指CPU 从一个进程或线程切换到另一个进程或线程。

2.2.5 在内核中实现线程
1.线程回收、信号
2.缺点:系统调用代价比较高
3.问题:当一个多线程进程创建新的进程时,会发生什么? 当一个信号到达时,应该由哪一个线程处理它?

2.2.6 混合实现
1.使用内核级线程,然后将用户级线程与某些或者全部内核线程多路复用起来。

2.2.7 调度程序激活机制
1. 目的:模拟内核线程的功能,但是为线程包提供通常在用户空间中才能实现的更好的性能和更大的灵活性
2. 基本思路:当内核了解到一个线程被阻塞之后,内核通知该进程的运行时系统,并且在堆栈中以参数形式传递有问题的线程编号和所发生事件的一个描述,一旦如此激活,运行时系统就重新调度其线程。
3.调度程序激活机制的一个目标是作为上行调用的信赖基础,这是一种违反层次系统内在结构的概念。

2.2.8 弹出式线程:
1.概念:一个消息的到达导致系统创建一个处理该信息的线程
2.优点:线程非常新,消息到达与处理开始之间的时间非常短。

2.2.9 使单线程代码多线程化
1.把单线程改写为多线程易犯的错误:全局变量问题(为每个线程赋予其私有的全局变量,访问方式:为全局变量分配一块内存;引入库过程);许多库过程不是可重入的(为每个过程提供一个包装器);信号管理问题;堆栈的管理
2.3 进程间通信(IPC)
1.三个相关的问题:一个进程如何把信息传递给另一个?确保两个或多个进程在关键活动中不会出现交叉;与正确的顺序有关
2.三个问题对于线程:第一个问题对线程而言比较容易,因为它们共享一个地址空间(在不同地址空间需要通信的线程属于不同进程之间通信的情况),但是另外两个问题同样适用于线程。
2.3.1 竞争条件
1.假脱机目录、打印机守护进程、out(指向下一个要打印的文件)、in(指向目录中的下一个空闲槽位)、Murphy法则(任何可能出错的地方终将出错)、竞争条件
2.3.2 临界区
1.解决竞争条件:利用互斥(以某种手法确保当一个进程在使用一个共享变量或文件时,其他进程不能做同样的操作)
2.临界区域(对共享内存进行访问的程序片段)
3.一个好的解决方案:(1)任何两个进程不能同时处于其临界区 (2)不应对CPU的速度和数量做任何假设 (3)临界区外运行的进程不得阻塞其他进程  (4)不得使进程无限期等待进入临界区
2.3.3 忙等待的互斥

1.屏蔽中断:
使每个进程在刚刚进入临界区后立即屏蔽所有中断,并在就要离开之前再打开所有中断
屏蔽中断对于操作系统本身而言是一项很有用的技术,但对于用户进程则不是一种合适的通用互斥机制
2.锁变量:
设置一个共享(锁)变量,0表示临界区没有进程,1表示已经有某个进程进入临界区。
3.严格轮换法:
使用turn(记录轮到哪个进程进入临界区)、忙等待、自旋锁(用于忙等待的锁)
违反了条件三:临界区外运行的进程不得阻塞其他进程
4.Peterson 解法
5.TSL指令:TSL RX,LOCK
测试并加锁、锁住内存总线不同于屏蔽中断、XCHG(替代的方法)
2.3.4 睡眠与唤醒
1.优先级反转问题、
2.sleep、wakeup:使进程在无法进入临界区时阻塞而不是忙等待。
3.生产者-消费者问题(有界缓冲区问题)、唤醒等待位

2.3.5 信号量
1.信号量:累计唤醒次数
2.两种操作:down(对应sleep),up(对应wakeup)
3.原子操作:指一组相关联的操作要么都不间断执行,要么都不执行。
4.用信号量解决生产者-消费者问题:
三个信号量:full(满缓冲槽数目)、empty(空缓冲槽数目)、mutex(确保生产者和消费者不会同时访问缓冲区,称为二元信号量)、
5.信号量的另一种用途:同步,与互斥不同

2.3.6 互斥量
1.互斥量:没有技术能力的信号量,可以处于两态之一:解锁和加锁
2.两个过程:mutex_lock、mutex_unlock
3.thread_yield、mutex_trylock
4.enter_region和mutex_lock的区别:前者通过忙等待,后者调用thread_yield将CPU放弃给另一个线程。

一. 快速用户区互斥量futex
1.futex(快速用户空间互斥):结合自旋锁和阻塞机制的优点,实现了基本的锁,但避免了陷入内核。
2.包括了一个内核服务和一个用户库

二. pthread中的互斥量
1.Pthread提供许多可以用来同步线程的函数,其基本机制是使用一个可以被锁定和解锁的互斥量来保护每个临界区

2.除了互斥量(原子性检查),还提供一种同步机制:条件变量(允许线程由于一些未达到的条件而阻塞,阻塞时使用)
3.互斥量和条件变量经常一起用:让一个线程锁住一个互斥量,然后当它不能获得它期待的结果时等待一个条件变量
4.条件变量不存在内存,信号量反之
*2.3.7* 管程
1.程序次序问题会导致死锁
2.管程(monitor):为了更易与编写正确的程序,提出的一种高级同步原语,是一个由过程、变量及数据结构等组成的一个集合,它们组成一个特殊的模块或软件包。是编程语言的组成部分。
3.管程重要特性之一:任意时刻管程中只能有一个活跃进程,这一特性使管程能有效地完成互斥。
4.管程实现阻塞的方法:引入条件变量和两个相关操作:wait、signal,wait操作必须在signal之前,因为条件变量会丢失。
*2.3.7* 管程
1.程序次序问题会导致死锁
2.管程(monitor):为了更易与编写正确的程序,提出的一种高级同步原语,是一个由过程、变量及数据结构等组成的一个集合,它们组成一个特殊的模块或软件包。是编程语言的组成部分。
3.管程重要特性之一:任意时刻管程中只能有一个活跃进程,这一特性使管程能有效地完成互斥。
4.管程实现阻塞的方法:引入条件变量和两个相关操作:wait、signal,wait操作必须在signal之前,因为条件变量会丢失。
*2.3.7* 管程
1.程序次序问题会导致死锁
2.管程(monitor):为了更易与编写正确的程序,提出的一种高级同步原语,是一个由过程、变量及数据结构等组成的一个集合,它们组成一个特殊的模块或软件包。是编程语言的组成部分。

3.管程重要特性之一:任意时刻管程中只能有一个活跃进程,这一特性使管程能有效地完成互斥。
4.管程实现阻塞的方法:引入条件变量和两个相关操作:wait、signal,wait操作必须在signal之前,因为条件变量会丢失
5.java管理管程的方法
6.信号量太低级了,而管程在少数几种编程语言之外又无法使用,而且这些原语均未提供机器间的信息交换方式,所以还需要其他方式。

2.3.8 信息传递
这种进程间通信的方法使用两条原语send和receive,它们像信号量而不像管程,是系统调用而不是语言成分,因此可以很容易地将他们加入到库例程中去
1.信息传递系统的设计要点
信息接收问题、进程命名问题、身份认证问题、性能问题
2.用信息传递解决生产者-消费者问题
消费者首先将N条空信息发给生产者,当生产者向消费者传递一个数据项时,它取走一条空信息并送回一条填充了内容的信息,通过这种方式,系统中的消息数保持不变,所以信息都可以存放在事先确定数量的内存中。
消息传递变体:按照进程地址编码、信箱(有缓存和无缓存(会合))
2.3.9 屏障
用于进程组而不是双进程的生产者消费者,在有些应用划分了若干阶段,并且规定,除非所有的进程都就绪准备着手下一个阶段,否则任何进程都不能进入下一个阶段,可以通过在每个阶段的结尾安置屏障来实现这种行为。
2.3.10 避免锁:读-复制-更新
在某些情况下,我们可以允许写操作来更新数据结构,窍门在于确保每个读取操作要么读取旧数据版本要么新数据版本。
读-复制-更新:将更新过程中的移除和再分配过程分离开来。
读取临界区、宽限期
(图2.38 84页)

*2.4 调度*
调度程序、调度算法
2.4.1 调度简介
进程切换的代价是比较高的
1.进程行为
当一个进程等待外部设备完成工作而被阻塞时,才是IO活动
计算密集型:具有较长时间的CPU集中使用而较小频度的IO等待
IO密集型:具有较短时间的CPU集中使用而较大频度的IO等待
随着CPU越来越快,更多的进程倾向于IO密集型,因为CPU的改进比磁盘的改进快得多。
2.何时调度
需要调度处理的情况:
(1)在创建一个新进程之后,需要决定是运行父进程还是子进程(任意决定)
(2)在一个进程退出时(从就绪进程中选择或者系统提供的空闲进程)
(3)当一个进程阻塞在IO和信号量上或由于其他原因阻塞时
(4)在一个IO中断发生时
根据如何处理时钟中断,可以把调度算法分为:非抢占式(挑选一个进程,运行至被阻塞或者自动释放CPU),抢占式(运行某个固定时段的最大值)
3.调度算法分类
三种环境:
(1)批处理
(2)交互式
(3)实时
实时系统只运行那些用来推进现有应用的程序,而交互式系统是通用的,它可以运行任何的非协作甚至是有恶意的程序
4.调度算法的目标
2.4.2 批处理系统中的调度
1. 先来先服务(非抢占式)
2. 最短作业优先(非抢占式)

3.最短剩余时间优先(抢占式)

2.4.3 交互式系统中的调度
1.轮转调度
分配时间片

2.优先级调度
可以很方便地将一组进程按照优先级分成若干类,并且在各类之间采用优先级调度,而在各类进程内部采用轮转调度

3.多级队列
4.最短进程优先
5.保证调度
6.彩票调度
7.公平分享调度


2.4.4 实时系统中的调度
硬实时:必须满足绝对的截止时间
软实时:可以容忍偶尔错失截止时间
实时系统中的事件可分为周期性事件或非周期性事件,还可分为静态或者动态的
可调度的条件
2.4.6 线程调度
2.5 经典的IPC问题
2.5.1 哲学家就餐问题
2.5.2 读者-写者问题
2.6 有关进程与线程的研究
2.7 小节

猜你喜欢

转载自blog.csdn.net/qq_28897525/article/details/79985672