1.进程概念

1.1 进程

进程包含了程序代码和当前活动(其中当前活动通过程序计数器和处理器寄存器的内容表示)两个部分,进程是执行中的程序。具体有:

  • 文本段(代码段)
  • 数据段(全局变量)
  • 栈(stack)(包含临时数据、函数参数、返回地址、局部变量)
  • 堆(heap)(进程运行期间动态分配的内存)
  • 程序计数器

注意:程序是被动实体,进程是活动实体(其中当前活动通过程序计数器和处理器寄存器的内容表示)
两个进程可以与同一程序联系,虽然文本段相同。但是数据段、堆栈段不同

进程是一个程序的一次执行过程。 进程是资源分配、保护和调度的基本单位

1.2 进程状态

进程有5种状态,包括:

  • New(新的)
  • Running(运行)
  • Waiting(等待)
  • Ready(就绪)
  • Terminated(终止) 第3章:进程 - 图1

    2. 进程调度

    2.1 进程切换

  • 并发进程中,一个进程再执行过程中可能会被另一个进程替换占有CPU,这个过程称作“进程切换”

image.png

  1. 是什么触发了进程切换?
  2. 进程切换时需要做什么?

2.1.1 中断技术

  • 中断是指程序执行过程中
    • 当发生某个事件时,中止CPU上现行程序的运行
    • 引出该事件的处理程序执行
    • 执行完毕返回原程序中断点继续执行

image.png

2.1.2 中断源

  • 外中断:来自处理器之外的硬件中断信号
    • 如始终中断、键盘中断、外围设备中断
    • 外部中断均是异步中断(随机中断)
  • 内中断(异常):来自于处理器内部,指令执行过程中发生的中断,属同步中断
    • 硬件异常:掉电、奇偶检验错误等
    • 程序异常:非法操作、地址越界、断点、除数为0
    • 系统调用

      2.2.3 中断的处理过程

      image.png
      • 特权指令:只能运行在内核模式下的指令
        • I/O操作
        • 关闭中断
        • 设置定时器
        • 进程切换
      • 非特权指令:运行在用户模式下的指令

2.2.4模式切换

  • 中断是用户态向核心态转换的唯一途径,系统调用实质上也是一种中断
  • OS提供Load PSW指令装载用户进程返回用户状态

image.png

2.2.5 进程切换

  • 切换时机:
    • 进程需要进入等待状态(主动切换:启动IO设备)
    • 进程被抢占CPU而进入就绪状态(高优先级进程抢占CPU;CPU时间到期)
  • 切换过程
    • 保存被中断进程的上下文信息
    • 修改被中断进程的控制信息(如状态等)
    • 将被中断的进程加入相应的状态队列
    • 调度一个新的进程并恢复它的上下文信息

image.png

进程切换和进程的中断有什么关系? 进程的切换发生在核心态,只有中断技术才能用户态进去到核心态

2.2 进程调度

2.2.1 进程控制块

每一个进程都需要分配一定的信息,这些信息的仓库就叫做PCB,PCB有以下功能:

  • 系统利用PCB 控制 管理 进程
  • PCB是进程存在的唯一标志

操作系统通过PCB感知进程的存在
PCB包含以下信息:
image.png

  • 进程状态(如上所述)
  • 程序计数器:表示进程要执行的下个指令的地址
  • CPU寄存器:与程序计数器一起,在出现中断时状态信息需要保存,使进程能够正确执行
  • CPU调度信息:包括优先级、调度队列的指针等
  • 内存管理信息:(详见第八章)
  • 记账信息:包括CPU时间、实际使用时间、时间界限、记账数据、作业和进程数量等
  • IO状态信息:分配给进程的IO设备列表,打开的文件列表等

    程序计数器与CPU寄存器的区别与联系: 电脑执行程序的过程就是cpu不断执行指令的过程。cpu执行指令的过程,第一步就是取指令,并将其放入指令寄存器,然后对指令译码,进行一些操作,最后计算下条指令的地址,并送入程序计数器。总之,一个用来存当前指令,一个用来存下条指令的地址。cpu根据程序计数器里的地址取指令,将取到的指令送指令寄存器。

image.png

3.2.2 进程调度

目的:使CPU的利用率最大化,需要优化进程调度的方法
进程调度程序选择一个进程到CPU上执行(一个CPU一个时间段只能执行一个程序,其余程序需要等待CPU空闲重新调度)

3.2.3 调度队列

作业(job)队列:包含了系统中所有的进程
就绪(Ready)队列:包含了系统中驻留在内存结构中就绪的,准备运行的进程
该队列通常用链表实现,头结点指向第一个和最后一个PCB块的指针,每个PCB块包括指向下一个PCB的指针域
设备(Device)队列:包含了等待特定IO设备的进程列表
进程可能会有IO请求,请求时可能IO设备在处理其他请求,所以该进程需要等待。
讨论进程调度的常用方法时队列图
image.png
其中包括了就绪队列和设备队列(可能有多个设备队列)
image.png

  1. 是什么触发了进程切换?

是因为发生了中断

第3章:进程 - 图11

3. 线程

 线程就是进程的执行流
image.png

3.1 线程的定义

线程是CPU使用的基本单元,由线程ID程序计数器寄存器集合和组成。它与属于同一进程的其他线程共享代码段,数据段和其他操作系统资源。
image.png

多线程的优点

  1. 响应度高:一个多线程的程序即使部分阻塞,其他部分仍能运行,从而增加了对用户的响应程度。
  2. 资源共享
  3. 经济:创建和切换线程比创建进程更节省资源和时间
  4. 多处理器体系结构的利用:多线程能充分利用多处理器体系

    3.2 多线程的模型

    提供多线程支持有两种方式:用户线程内核线程
  • 用户线程受内核支持,无需内核管理
  • 内核线程由操作系统支持和管理

image.png
在用户线程和内核线程之间存在一定的关系,即多线程模型,以下讨论三种常用的关系:多对一,一对一,多对多。

1. 多对一模型

多个用户线程映射到一个内核线程

  • 优点:线程管理由线程库在用户空间完成,效率比较高
  • 缺点:如果一个线程阻塞,整个进程就会阻塞;且多个线程无法并行运行在多处理器上

image.png

2. 一对一

每个用户线程映射到一个内核线程上

  • 优点:比多对一模型更好的并发功能;一个线程阻塞时,其他线程能够继续调用;多个线程能够并发运行在多处理器
  • 缺点:创建内核线程的开销会影响应用程序的功能

image.png

3. 多对多

  • 多对一模型可以创建任意多的用户线程,但是只能没有增加并发性
  • 一对一模型增强了并发性,但开发者要小心不能在应用程序中创建太多的进程

多对多模型没有上述的所有缺点,它多路复用了许多用户线程到同样数量或更小数量的内核线程上
image.png

3.3 线程库

在用户空间中提供一个没有内核支持的库 执行一个由操作系统直接支持的内核级的库

3.4 多线程问题

3.4.1 系统调用fork()和exec()

  • 在多线程程序中,系统调用fork()和exec()的语义有所改变。
  • 如果程序中一个进程调用fork(),那么新进程会复制所有线程,还是新进程只有单个线程?有的UNIX系统有两种形式的fork(),一种复制所有线程,另一种只复制调用了系统调用fork()的线程。
  • Exec()工作方式:如果一个线程调用系统调用exec(),那么exec()参数所指定的程序会替换整个进程,包括所有线程。
  • 如果调用fork()之后立即调用exec(),那么没有必要复制所有线程,因为exec()参数所指定的程序会替换整个进程。在这种情况下,只复制调用线程比较适当。不过,如果在fork()之后另一进程并不调用exec(),那么另一进程就应复制所有进程。

    3.4.2 取消

    线程取消(thread cancellation)是在线程完成之前来终止线程的任务。

要取消的线程通常称为目标线程。目标线程的取消可在如下两种情况下发生:

一是异步取消(asynchronous cancellation):一个线程立即终止目标线程。

二是延迟取消(deferred cancellation):目标线程不断地检查它是否应终止,这允许目标线程有机会以有序方式来终止自己。

如果资源已经分配給要取消的线程,或者要取消的线程正在更新与其他线程所共享的数据,那么取消会有困难,对于异步取消尤为麻烦。操作系统回收取消线程的系统资源,但是通常不回收所有资源。因此,异步取消线程并不会使所需的资源空闲。相反采用延迟取消时,允许一个线程检查它是否是在安系统资源空闲全的点被取消,pthread称这些点为取消点(cancellation point)。

3.4.3 信号处理

信号处理:信号在Unix中用来通知进程某个特定时间已发生了,信号可以同步或异步接收。所有有信号具有同样的模式:

(1)信号有特定事件的发生所产生

(2)产生的信号要发送到进程

(3)一旦发送,信号必须交易处理。

同步信号的例子包括访问非法内存或被0除。在这种情况下,如果运行程序执行这些动作,那么就产生信号,同步信号发送到执行操作而产生信号的同一进程(同步的原因)。

当一个信号由运行进程之外的事件产生,那么进程就异步接收这一信号。这种信号的例子包括使用特殊键(Ctrl + C)或者定时器到期。通常,异步信号被发送到另一个进程。

每个信号可能由两种可能的处理程序中的一种来处理:

(1)默认信号处理程序

(2)用户定义的信号处理程序

每个信号都有一个默认信号处理程序,当处理信号是在内核中运行的,这种默认动作可以用用户定义的信号处理程序来改写。信号可以按照不同的方式处理。有的信号可以简单的忽略(如改变窗口大小),有的需要终止程序来处理(非法内存访问)

单线程程序的信号处理比较直接,信号总是发送给进程。

当多线程时,信号会

(1)发送信号到信号所应用的线程

(2)发送信号到进程内的每个线程

(3)发送信号到进程内的某些固定线程

(4)规定一个特定线程以接收进程的所有信号。

发送信号的方法依赖于信号的类型。

3.4.4 线程池

多线程服务器有一些潜在问题:第一个是关于处理请求之前用以创建线程的时间,以及线程在完成工作之后就要被丢弃这一事实。第二个,如果允许所有并发请求都通过新线程来处理,那么将没法限制在系统中并发执行的线程的数量。无限制的线程会耗尽系统资源。解决这一问题是使用线程池。

线程池的思想是在进程开始时创建一定数量的线程,并放入到池中以等待工作。当服务器收到请求时,他会唤醒池中的一个线程,并将要处理的请求传递给他,一旦线程完成了服务,它会返回到池中在等待工作。如果池中没有可用的线程,那么服务器会一直等待直到有空线程为止。

线程池的优点:

(1)通常用现有线程处理请求要比等待创建新的线程要快

(2)线程池限制了在任何时候可用线程的数量。

线程池中的线程数量由系统CPU的数量、物理内存的大小和并发客户请求的期望值等因素决定。比较高级的线程池能动态的调整线程的数量,以适应具体情况。

3.4.5 线程特定数据

同属一个进程的线程共享进程数据。
在某些情况下每个线程可能需要一定数据的自己的副本,这种数据称为线程特定数据。可以让每个线程与其唯一的标识符相关联。