操作系统学习笔记(二)——进程与线程

二、进程与线程

1 进程

(1) 进程的创建、终止和层次结构

创建

   UNIX中,只有一个系统调用可以创建进程,fork。在UNIX和Windows中,进程创建后,父进程和子进程有各自不同的地址空间,但也有可能共享某些只读数据,可写的内存时不可以共享的,或者通过写时复制的方式

终止

  • 正常退出
  • 出错退出
  • 严重错误
  • 被其他进程杀死

层次结构

   在UNIX中,进程和它的所有子进程以及后裔共同组成一个进程组。当用户从键盘发出一个信号时,该信号被送给当前与键盘相关的进程组中的所有成员(他们通常是在当前窗口创建的所有活动进程)。每个进程可以分别捕获该信号、忽略该信号或采取默认的动作。考虑不同软件的热键冲突
疑问

所有进程都是init进程的子进程怎么说???

(2) 进程的状态

  • 运行态
  • 就绪态
  • 阻塞态

(3) 进程的实现

进程表 每个进程占用一个进程表项,该表项包含了进程状态的重要信息,包括程序计数器、堆栈指针、内存分配状况、所打开文件的状态、账号和调度信息,以及其他在进程由运行态转换到就绪态或阻塞态时必须包含的信息
在典型的系统中包含如下关键字段;
1 进程管理相关
包含三大类信息;
1)标识信息:用于唯一地标识一个进程,包括进程ID、父进程、进程组等。
2)现场信息:用于保留一个进程在运行时存放在处理器现场中的各种信息。它们用于在进程切换是保存处理器现场和恢复处理器现场。包括通用寄存器、PSW、堆栈指针、程序计数器等。
3)控制信息:用于管理和调度一个进程。包括进程开始时间、使用CPU的时间等。
2 存储管理相关
1)正文段指针
2)数据段指针
3)堆栈段指针等
3 文件管理相关
根目录、工作目录、文件描述符、用户ID、组ID等
中断响应
在这里插入图片描述
在这里插入图片描述

4 多道程序设计模型

假设一个进程等待IO操作的时间与其停留在内存中时间的比为p,当内存中同时存在n个进程时,

CPUutilization=1-p^n

2 线程

(1)使用线程的原因

  • 可以共享地址空间
  • 线程更轻量级,创建和销毁更容易
  • 线程在IO密集型程序中可以提高效率
  • 适应多处理器系统
    进程用于把资源集中在一起,而线程则是在CPU上被调度执行的实体

(2)需要注意的问题

  • 线程拥有程序计数器、寄存器、堆栈
  • 如果子进程拥有了和父进程一样的多个线程,对于某一事件的响应是父进程响应还是子进程,亦或者都响应
  • 与共享数据结构的事实有关
    如果一个线程关闭了某个文件,另一个线程还在该文件上进行读操作时会怎样

(3)线程的实现

用户线程与内核线程

1 .内核级线程:由操作系统内核创建和撤销。内核维护进程及线程的上下文信息以及线程切换。一个内核线程由于I/O操作而阻塞,不会影响其它线程的运行。Windows NT和2000/XP支持内核线程。
2.用户线程指不需要内核支持而在用户程序中实现的线程,其不依赖于操作系统核心,应用进程利用线程库提供创建、同步、调度和管理线程的函数来控制用户线程。不需要用户态/核心态切换,速度快,操作系统内核不知道多线程的存在,因此一个线 程阻塞将使得整个进程(包括它的所有线程)阻塞。由于这里的处理器时间片分配是以进程为基本单位,所以每个线程执行的时间相对减少。但不能很好的利用多核Cpu,目前Linux pthread大体是这么做的。
  用户线程运行在一个中间系统上面。目前中间系统实现的方式有两种,即运行时系统(Runtime System)内核控制线程。“运行时系统”实质上是用于管理和控制线程的函数集合,包括创建、撤销、线程的同步和通信的函数以及调度的函数。这些函数都驻留在用户空间作为用户线程和内核之间的接口。用户线程不能使用系统调用,而是当线程需要系统资源时,将请求传送给运行时,由后者通过相应的系统调用来 获取系统资源。内核控制线程:系统在分给进程几个轻型进程(LWP),LWP可以通过系统调用来获得内核提供的服务,而进程中的用户线程可通过复用来关联 到LWP,从而得到内核的服务。

以下是用户级线程和内核级线程的区别

(1)内核支持线程是OS内核可感知的,而用户级线程是OS内核不可感知的。
(2)用户级线程的创建、撤消和调度不需要OS内核的支持,是在语言(如Java)这一级处理的;而内核支持线程的创建、撤消和调度都需OS内核提供支持,而且与进程的创建、撤消和调度大体是相同的。
(3)用户级线程执行系统调用指令时将导致其所属进程被中断,而内核支持线程执行系统调用指令时,只导致该线程被中断。
(4)在只有用户级线程的系统内,CPU调度还是以进程为单位,处于运行状态的进程中的多个线程,由用户程序控制线程的轮换运行;在有内核支持线程的系统内,CPU调度则以线程为单位,由OS的线程调度程序负责线程的调度。
(5)用户级线程的程序实体是运行在用户态下的程序,而内核支持线程的程序实体则是可以运行在任何状态下的程序。

内核线程的优点
当有多个处理机时,一个进程的多个线程可以同时执行。

缺点

由内核进行调度。

用户进程的优点

(1) 线程的调度不需要内核直接参与,控制简单。
(2) 可以在不支持线程的操作系统中实现。
(3) 创建和销毁线程、线程切换代价等线程管理的代价比内核线程少得多。
(4) 允许每个进程定制自己的调度算法,线程管理比较灵活。
(5) 线程能够利用的表空间和堆栈空间比内核级线程多。
缺点

(1)资源调度按照进程进行,多个处理机下,同一个进程中的线程只能在同一个处理机下分时复用

(4)调度程序激活机制

为了使用户线程像内核线程一样工作,一个线程阻塞时不会阻塞整个进程,而是切换到另一个就绪的线程。采用上行调用的方法,内核调用用户空间的运行时系统,通知运行时系统一个线程是否阻塞或已经就绪,由运行时系统决定是否运行。

3 进程间通信 inter process communication IPC

(1)竞争条件

两个或多个进程读写某些共享数据,而最后的结果取决于进程运行的精确时序,称为竞争条件。

(2)临界区

把对共享内存进行访问的程序片段称作临界区域或临界区。如果能够适当的安排,使得两个进程不可能同时处于临界区中,就能够避免竞争条件。
对于一个好的方案,需要满足以下四点要求:

  • 任何两个进程不能同时处于其临界区
  • 不应对CPU的速度和数量做任何假设
  • 临界区外运行的进程不得阻塞其他进程
  • 不得使进程无限期等待进入临界区

(3)忙等待的互斥

几种实现互斥的方案

屏蔽中断

当进程进入临界区后立即屏蔽所有中断,离开之前再打开中断,这样CPU不会被切换到其他进程。此方法对于用户进程不是一种合适的互斥机制,而且在多核CPU上也不适用

锁变量

设置一个变量,用0和1来表示有无进程进入临界区,但是仍有可能导致竞争条件

严格轮换法

在一个进程比另一个慢了很多的情况下,轮流进入临界区违反了条件3,即临界区外运行的进程不得阻塞其他进程

Peterson解法

TSL指令

需要硬件支持的一种方案。对于多处理器计算机,都有下面一条指令TSL RX,LOCK,称为测试并加锁。执行TSL指令的CPU将锁住内存总线,以禁止其他CPU在本指令结束之前访问内存

(4)睡眠与唤醒

Peterson和TSL解法都是正确的,但都有忙等待的缺点。当一个程序想进入临界区时,先检查是否允许进入,若不允许,则该进程原地等待,直到允许为止。这不近浪费了CPU时间,还可能出现优先级反转问题

生成者-消费者问题 使用sleep与wakeup同样会导致竞争条件,甚至导致进程永远睡眠下去,可以加入唤醒等待位来避免,但是没有从根本上解决问题

(5)信号量

相比于睡眠唤醒,引入了一个新的变量类型,称作信号量,一个信号量的取值可以为0或者正值,设立两种操作,down和up,对应于sleep和wakeup。
检查数值、修改变量值以及可能发生的睡眠操作均为一个单一的、不可分割的原子操作完成。保证一旦一个信号量操作开始,则在该操作完成或阻塞之前,其他进程均不允许访问该信号量。这种原子性对于解决同步问题和避免竞争条件是绝对必要的。所谓原子操作,实质一组相关联的操作要么都不间断地执行,要么都不执行。
通常将up和down作为系统调用实现,而且操作系统只需在执行以下操作时暂时屏蔽全部中断:测试信号量、更新信号量以及在需要时使某个进程睡眠

(6)互斥量

如果不需要信号量的计数能力,有时可以使用信号量的一个简化版本,称为互斥量。互斥量是一个可以处于两态之一的变量:解锁和加锁

  • 快速用户区互斥量 futex
  • pthread中的互斥量

(7)管程

  1. 管程可以看做一个软件模块,它是将共享的变量和对于这些共享变量的操作封装起来,形成一个具有一定接口的功能模块,进程可以调用管程来实现进程级别的并发控制。
    
  2. 进程只能互斥得使用管程,即当一个进程使用管程时,另一个进程必须等待。当一个进程使用完管程后,它必须释放管程并唤醒等待管程的某一个进程。
    
  3. 在管程入口处的等待队列称为入口等待队列,由于进程会执行唤醒操作,因此可能有多个等待使用管程的队列,这样的队列称为紧急队列,它的优先级高于等待队列。
    

(7)消息传递

信号量太低级,而管程在少数几种编程语言之外又无法使用,并且,这些原语均为提供机器间的信息交换方法。
消息传递使用两条原语,send 和 receive

(8)屏障

用于一组进程同步

(9)避免锁:读-复制-更新

4 调度

非抢占式调度算法挑选一个进程,然后让该进程运行直至被阻塞或该进程自动释放CPU;抢占式调度算法挑选一个进程,并且让该进程运行某个固定时段的最大值

(1)调度算法分类

不同的应用领域有不同的目标,因此不同环境下调度程序的优化是不同的,划分出三种环境:

  • 批处理
  • 交互式
  • 实时

(2)调度算法的目标

几个通用性的目标:

  • 公平,每个进程公平的得到CPU份额
  • 策略强制执行,保证规定的策略被执行
  • 平衡-保持系统的所有部分忙碌
    几个关键词:吞吐量、周转时间、CPU利用率、响应时间、均衡性

(3)批处理系统中的调度

  • 先来先服务 按请求CPU的顺序使用CPU,如果进程阻塞就会排到队列末尾
  • 最短作业优先 可以使得平均周转时间最短
  • 最短剩余时间优先可以使新的短作业获得良好的服务

(4)交互式系统中的调度

  • 轮转调度 CPU时间片长度的选择,过短的话上下文切换开销大,太长又可能使得对短的交互请求响应时间变长,典型时间20-50ms
  • 优先级调度
  • 多级队列 时间片和优先级相关
  • 最短进程优先
  • 保证调度
  • 彩票调度
  • 公平分享调度 考虑不同用户的进程

(5)策略和机制

可以将调度机制和调度策略分离,以使得用户进程可以参与到调度中来

经典的IPC问题

哲学家就餐问题

读者-写者问题

猜你喜欢

转载自blog.csdn.net/u010069259/article/details/89843334