计算操作系统--进程与线程

计算机操作系统

进程

进程是操作系统中最核心的概念,它是一个正在执行程序的实例,是对正在运行程序的一个抽象。
注意:在单cpu核心系统中,在某一时刻,有且仅有一个进程,处于运行状态。cpu通过在多道进程间快速切换来实现并行,由此称之为伪并行。与多处理器系统相区别。

进程模型

顺序进程又称进程,用于描述并行的一种系统概念。在进程模型中,计算机中所有可运行的软件都被组织成顺序进程。同时,通过对进程模型的抽象能够不必考虑中断、定时器以及上下文切换,只需要考虑并行进程。
注意:要区分进程程序之间的区别。进程是一个程序动态执行的过程,包含“程序”、“输入”、“输出”以及“状态”。

进程创建

创建进程的4中情况

  1. 系统初始化。
  2. 正在运行的程序执行了创建进程的系统调用。
  3. 用户请求创建一个新进程。
    • 交互式系统中键入命令或点击图标都会产生一个进程。
  4. 一个批处理作业的初始化(仅限在大型机的批处理操作系统中应用)。

守护进程:停留在后台处理的进程

新进程都是由一个已存在的进程执行一个用于创建进程的系统调用而产生的。

在UNIX系统当中,用于创建新进程的系统调用:forkfork会创建一个与调用进程相同的副本,其中父子进程拥有相同的内存映像、环境字符串以及打开文件等,子进程通过execve改变其内存映像。在window系统中,用于创建新进程的系统调用:CreateProcessCreateProcess即处理创建进程,同时负责装入新的程序。

进程创建后,父子进程拥有不同的地址空间。

  • 在UNIX系统当中,子进程的初始地址空间是父进程的一个副本。
    • 不可写的内存区域是共享的,部分系统可实现程序正文共享。
    • 子进程共享父进程所有的内存,但通过写时复制的方式进行共享。
  • 在windows系统中,父子进程的地址空间一开始就不相同

进程终止

在UNIX系统通过系统调用exit(在Windows中为ExitProcess)通知操作系统工作完成。
其中,引发进程终止的4种条件:

  1. 正常退出
  2. 出错退出
  3. 严重错误 --> 通常由程序错误(非法指令、引用不存在的内存,除零异常等)导致。在一些系统当中,进程可以通知操作系统,能够自行处理某些类型的错误,在这类错误当中,进程会收到信号(中断),从而不至于被终止。
  4. 被其他进程杀死。killTerminateProcess

进程的层次结构

在部分操作系统(UNIX)当中,进程被组织成为一颗树的结构,进程和其子进程以及其后续后裔进程共同组成为一个进程组。在UNIX系统中,init进程 作为启动映像,负责初始化后续终端进程,等待用户登录,整个系统中的所有进程都是属于以init为根的进程。

而在Windows系统中没有进程层次的概念,所有进程的地位都是相同的。父进程创建子进程时,会得到子进程的句柄,从而控制其子进程。但是该进程能够将该句柄转移至其他进程,因此不存在进程层次,而UNIX系统不行。

进程状态

进程拥有三种状态:

  1. 运行态(该时刻进程实际占有cpu)
  2. 就绪态(可运行状态,但不拥有cpu资源)
  3. 阻塞态(除非某种外部事件发生,否则进程不能运行)

进程状态转换图

调度程序选择另一个进程
进程因等待输入被阻塞
调度程序选择该进程
出现有效输入
运行
就绪
阻塞

操作系统最底层是进程调度程序,所有关于中断处理、启动进程、停止进程的具体细节都隐藏在调度程序中。

进程实现

操作系统在内部维护者一张表格(进程表),从而实现进程模型。每个进程占用一个进程表项(进程控制块)其中包含了进程状态的重要信息,包括程序计数器、堆栈指针、内存分配状况、打开文件状态、账号以及调度信息等。

与每一I/O类关联的是一个称作中断向量的位置,包含了中断服务程序的入口地址。
中断发生后操作系统底层所需要进程的工作:

  1. 硬件压入堆栈程序计数器等。
  2. 硬件从中断向量中装入新的程序计数器。
  3. 汇编语言过程保存寄存器值
  4. 汇编语言过程设置新的堆栈
  5. C中断服务历程运行(典型:读和缓冲输入)。
  6. 调度程序决定下一个运行的进行。
  7. C过程返回至汇编代码。
  8. 汇编语言过程开始运行新的当前进程。

线程

线程又称迷你进程,在传统的操作系统中,每个进程都有一个地址空间和一个控制线程,在同一地址空间中运行多个控制线程。

线程的使用

多线程概念:

  1. 并行实体(线程)拥有共享同一个地址空间和所有可用数据的能力。
  2. 线程比进程更轻量级,更容易创建和撤销。
  3. 关于性能方面,程序存在大量的计算或I/O处理,多线程能够运行多个活动重叠进行,从而加快应用程序执行的速度。

编程模型

模型特性
多线程并行性、阻塞系统调用(易于编程)
单线程进程无并行性、阻塞系统调用
有限状态机并行性、非阻塞系统调用、中断(不易于编程)

经典线程模型

进程模型基于两种独立的概念:资源分组处理与执行。
线程拥有寄存器,用来保存线程当前的工作变量,拥有堆栈,用来记录执行记录,其中每一帧保存了一个已调用的但是还未从中返回的过程。
进程与线程的区别:

  1. 进程中并行运行多个线程。
  2. 进程是资源的拥有者。
  3. 线程不拥有资源,但是在CPU上被调度的实体。
  4. 线程被成为轻量级进程

在一个进程内的所有线程都有完全一样的地址空间,意味着:

  1. 能够共享全局变量。
  2. 各个线程能够访问进程内任意地址,因此一个线程能读、写以及清除另一个线程的堆栈。
    同时,所有线程共享打开文件集子进程定时器以及相关信号。

线程状态:运行、阻塞、就绪或终止。

POSIX线程

IEEE设定的线程标准,能够实现可移植的线程程序。其定义的线程包为pthread

所有的pthread都包含一个标识符、一组寄存器以及一些属性(堆栈大小、调度参数等)。

线程调度描述
pthread_create创建一个线程,线程标识符会被作为函数返回值返回。
pthread_exit结束调用的线程。
pthread_join等待一个特定的线程退出。
pthread_yield释放CPU来运行另外一个线程。不同于进程,线程库无法根据时钟中断强制线程让出CPU。需要借用thread_yield自动放弃CPU。
pthread_attr_init创建并初始化一个线程的属性结构,并作为默认值。
pthread_attr_destroy删除一个线程的属性结构 ,且不影响调用它的线程。

用户级线程与内核级线程

用户级线程

用户空间内创建的线程,成为用户级线程。每个进程都需要专用的线程表,用来追踪该进程中的线程。该线程表由运行时系统管理。
优点:

  1. 保存线程状态的过程和调度程序都只是本地过程,所以启动效率高于内核调用。同时,线程不需要在陷入内核,不需要上下文切换,也不需要对内存高速缓存进行刷新。
  2. 运行进程使用自己的调度算法。
    缺点:
  3. 实现阻塞调用?运行每个线程进行阻塞调用,同时还有避免影响到其他线程。目前系统调用会导致整个进程阻塞。
  4. 系统调用可以全部改为非阻塞的。
  5. 替代方案:包装器 select,在某个调用会阻塞时,会提前通知,只有在安全的状态(调用不阻塞)下才会进行系统调用,否则阻塞当前线程,运行其他线程,直至下一次再次进入运行状态重复上述操作。
  6. 缺页中断问题
  7. 线程调度问题
内核级线程

内核空间中创建的线程,在内核中记录所有线程的线程表,内核中的线程表保存了每个线程的寄存器、状态和其他信息,与用户空间中的线程一致。
优点:

  1. 不需要其他非阻塞系统调用。
  2. 在发生缺页中断时,系统能够检查该进程其他线程能否继续运行。
    缺点
  3. 在内核中创建和销毁线程代价较大,部分系统采用回收线程的策略。
混合实现

用户线程内核线程进行多路复用。在这个模型中,每个内核级线程有一个可以轮流使用的用户级线程集合。

调度程序激活机制

尽管内核级线程在一些关键点上优于用户级线程,但是内核级线程速度慢。因此寻找保持其优良特性的前提下改进其速度的方法,称为调度程序激活机制。
工作目标:模拟内核线程的功能,同时避免了在用户空间和内核空间之间的不必要的转换,提高效率。
基本思路:当内核了解到一个线程被阻塞之后,内核通知该进程的运行时系统,并且在堆栈中以参数的形式传递有问题的线程编号和所发生事件的一个描述。内核通知该进程的运行时

弹出式线程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值