5、进程/线程模型2(操作系统笔记)

五、深入理解进程概念

5.1 进程的分类

  • 1、系统进程/用户进程
    这里系统进程的优先级要高

  • 2、前台进程/后台进程
    用户一般只和前台进程交互。

  • 3、CPU密集型进程/IO密集型进程

5.2 进程层次结构

  • UNIX中是一个进程家族树的概念:init为根进程。于是如果某一个进程结束了,那么其子孙进程都必须结束。
  • Windows中的所有进程的地位都是相同的。

5.3 进程和程序的区别

  • 进程更能准确刻画并发,而程序不能
  • 程序是静态的,进程是动态的
  • 进程有生命周期的,有诞生有消亡,是短暂的;而程序是相对长久的
  • 一个程序可对应多个进程
  • 进程具有创建其他进程的功能

5.4 进程的地址空间

操作系统为每个进程分配了一个地址空间。这里我们看一个例子:


5、进程/线程模型2(操作系统笔记)_第1张图片
1

这个程序我们从命令行中输入数据,比如:

myval 7
myval 8

此时我们会发现虽然进程不同,但是打印出来的地址确实一样的。这里我们从进程地址空间来分析:

5、进程/线程模型2(操作系统笔记)_第2张图片
2

说明:上面的两个进程都有这样一个地址空间,也就是说这两个进程是在不同的地址空间上的相同的位置,所以虽然地址是一样的,但是实际上在实际内存中的地址是不一样的。

5.5 进程映像

对进程执行活动全过程的静态描述(快照)。由进程地址空间内容、硬件寄存器内容及与该进程相关的内核数据结构、内核栈组成

  • 与用户相关:进程地址空间(代码段、数据段、堆和栈、共享栈等)
  • 与寄存器相关:程序计数器、指令寄存器、程序状态寄存器、栈指针、通用寄存器等的值
  • 与内核相关:
    • 静态部分:PCB及各种资源数据结构
    • 动态部分:内核栈(不同进程在进入内核后使用不同的内核栈)

5.6 上下文切换

  • CPU硬件状态从一个进程换到另一个进程的过程称为上下文切换,其实就是运行环境的切换。
  • 进程运行时,其硬件状态保存在CPU上的寄存器中。寄存器有:程序计数器、程序状态寄存器、栈指针、通用寄存器、其他控制寄存器的值
  • 进程不运行时,这些寄存器的值保存在进程控制块中;当操作系统要运行一个新的进程时,将进程控制块中相关值送到对应的寄存器中。

六、线程

6.1 线程的引入

引入线程有三个理由:

  • 应用的需要
  • 开销的考虑
  • 性能的考虑

6.1.1 应用的需要

我们看一个例子,一个web服务器的工作方式:

  • 从客户端接收网页请求
  • 从磁盘上检索相关的网页,读入内存(此时进程是停止的,直到读取完毕)
  • 将网页返回给对应的客户端

可以看到每次从磁盘读取的时候进程都是暂停的,这样会导致性能低下。那如何提高服务器的工作效率?通常情况下是使用网页缓存的方式解决。如果没有线程的情况下的两种解决方案:

  • 一个服务进程
    这种情况下也是一种顺序编程,虽然采用了缓存机制,但是性能同样不高。而如果设置多个进程,这多个进程之间又是相互独立的,有独立的地址空间,所以不能共享信息。

  • 有限状态机
    这种方式编程模型复杂,采用非阻塞的I/O

多线程的解决方式

5、进程/线程模型2(操作系统笔记)_第3张图片
1

说明:这是一个多线程的 web服务器的工作方式,首先读取客户端的请求,之后由分派线程将各个任务分派给工作线程,同样这里还是采用了网页缓存。于是我们可以看到一个 web服务器的实现有三种方式:
5、进程/线程模型2(操作系统笔记)_第4张图片
2

6.1.2 开销的考虑

5、进程/线程模型2(操作系统笔记)_第5张图片
3

6.1.3 性能的考虑

如果有多个处理器的话,一个进程就会有多个线程同时在执行了,这样可以极大的提高运行 性能。

6.2 线程的基本概念

5、进程/线程模型2(操作系统笔记)_第6张图片
4

线程的属性

  • 有标识符ID
  • 有状态及状态转换-->需要提供一些操作
  • 不运行时需要保存的上下文(程序计数器等寄存器)
  • 有自己的栈和栈指针
  • 共享所在进程的地址空间和其他资源
  • 创建、撤销另一个线程(程序开始是以一个单线程方式运行的)

6.3 线程机制的实现

一般有三种实现机制:

  • 用户级线程
  • 核心级线程
  • 混合(两者结合)方法

6.3.1 用户级线程

5、进程/线程模型2(操作系统笔记)_第7张图片
5

说明:可以看到线程是有运行时系统管理的,在内核中只有进程表。典型例子就是 UNIX:
POSIX线程库--PTHREAD
5、进程/线程模型2(操作系统笔记)_第8张图片
6

小结:
有点:

  • 线程切换快
  • 调度算法是应用程序特定的
  • 用户级线程可运行在任何操作系统上(只需要实现线程库)

缺点:

  • 内核只将处理器分配给进程,同一进程中的两个线程不能同时运行于两个处理器上
  • 大多数系统调用是阻塞的,因此,由于内核阻塞进程,故进程中所有线程也被阻塞。(可以在调用之前判断进行解决,如果是阻塞线程,那么就换其他线程)

6.3.2 核心级线程

5、进程/线程模型2(操作系统笔记)_第9张图片
7

6.3.3 混合模型

  • 线程创建在用户空间完成
  • 线程调度等在核心态完成
  • 例子如Solaris操作系统

你可能感兴趣的:(5、进程/线程模型2(操作系统笔记))