线程及其实现

195 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 17 天,点击查看活动详情


引入多线程的动机

进程有什么问题呢?

  • 进程切换开销大
  • 进程通信代价大
  • 进程间的并发粒度较粗,并发度不高

进程的两个重要功能

独立分配,被调度分派执行

进程作为系统资源分配和保护的独立单位,不需要频繁的切换

线程作为系统调度和分配的基本单位,能轻装运行,会被频繁的调度和切换

与进程相比,线程的优点

  1. 快速线程切换。同以进的多线程切换只需改变堆栈和寄存器,地址空间不变。
  2. 通信易于实现
  3. 减少管理开销
  4. 并发程度提高

多线程环境中的进程和线程

线程是操作系统进程中能够独立执行的实体,是处理器调度和分配的基本单位。线程是进程的组成部分,这些进程共享线程多获得的内存空间和资源。

线程组成

  • 线程唯一标识及其线程状态信息
  • 未运行时保存的线程上下文;可把线程看成进程中一个独立的程序计数器(PC)在操作
  • 核心栈,核心态下工作时,保存参数,函数调用时的返回值等
  • 用于存放线程局部变量器用户栈的私有存储区

线程又称轻量级进程

  • 线程运行在进程的上下文中,并使用进程的资源和环境
  • 系统调度的基本单位是线程而不是进程,每当创建一个进程时,至少要同时为该进程创建一个线程,否则该进程无法被调度执行。

线程的状态

线程状态有:运行、就绪和阻塞态等,线程的状态转换与进程的转换类似。

挂起状态对线程(在描述上)是没有意义的,如果进程挂起后被对换出内存,则它的所有线程因共享了进程的地址空间,也必须对换出去。

线程的实现

从实现的角度看,线程分为:用户级线程、内核级线程、混合式线程

内核级线程

线程管理的所有工作都是由内核完成的,应用程序只有一个访问内核级线程设施的API。内核维护进程和线程的上下文信息,调度对象是线程。

优点

内核可以调度同一个进程中的所有线程,内核自身也可以是多线程的(多cpu)

缺点

线程需要切换到内核,开销比较大。

用户级线程

用户级线程是指线程的管理由应用程序完成,在用户空间中实现,内核无需感知线程的存在。

优点

线程切换的开销小、所有线程管理的数据结构均在用户空间中、可以节省模式转换开销和内核的宝贵资源、可以不修改内核,用户级线程就可以运行在任何操作系统中

缺点

用户级线程阻塞就会导致整个系统的阻塞、不能利用多处理计数

进程的控制和管理

把处于同一状态的所有PCB链接在一起的数据结构称为进程队列。

进程切换是让处于运行态的进程中断运行,让出处理器,也就是做一次进程上下文切换,即保存老进程状态而装入被保护/保存了的新进程的状态,以便新进程运行。

当中断发生的时候,暂时中断正在执行的用户进程,把处理器的状态从用户状态切换到内核状态。

对于进程的控制和管理包括创建进程、阻塞进程、唤醒进程、挂起进程、激活进程、终止进程和撤销进程。

进程创建

  1. 申请空白的pcb
  2. 申请内存资源
  3. 初始化进程控制块
  4. 将新进程插入就绪队列

进程撤销

  1. 从pcb集合中检索出该进程的pcb
  2. 将被终止进程的所有资源归还父进程或者系统

进程阻塞

  1. 进程调用阻塞原语把自己阻塞,立即停止执行,保存现场信息
  2. 改变进程的状态————运行态改为等待态,插入有关等待队列

进程唤醒

  1. 把阻塞进程从等待该事件的阻塞队列中移除,其状态改成就绪态
  2. 等待被调度

进程挂起

  1. 检测要被挂起的状态,然后把相应的状态变成挂起状态
  2. 把进程的pcb非常驻部分交换到磁盘的对换区

进程激活

  1. 把进程pcb非常驻部分从磁盘中调入到内存中
  2. 然后把状态修改过来