一、概述
1.引入原因
-
性能:
- 进程是重量级的,负载了程序运行的所有内容,进程操作开销大
- Unix的轻型进程(fork)
-
应用:
- 进程代码有并行执行的需求
- 进程代码有并行执行的需求
-
硬件:
- 多核处理器已经是主流硬件
- 加速进程的运行
2.概念
- 线程(轻型进程,LWP)
- 进程内的一个代码片段可以被创建为一个线程
- 线程的状态:就绪、运行、等待等
- 线程的操作:创建、撤销、等待、唤醒
- 进程依旧是资源分配的基本单位
- 线程自己不拥有完整的系统资源,通过进程申请资源
- 与同一进程的其他线程共享代码段、数据段和其他操作系统资源
3.线程和进程
- 传统进程:
- 可称为重型进程(heavy weight process)
- 等价于只有一个线程的任务,主线程
- 单线程模型
4.线程结构
- 代码和数据:来自进程
- 各类资源:来自进程
- 线程控制块(Thread Control Block,TCB)
- 线程ID
- 线程计数器PC
- 寄存器集
- 栈空间
5.线程优点
- 响应度高:
- 线程创建开销小
- 例:Web服务器
- 资源共享:
- 进程中的线程可以共享进程资源
- 经济性:
- 线程创建、上下文切换比进程快
- MP体系结构的运用:
- 一个进程中的线程在不同处理器上并行运行,缩短了运行时间
- 一个进程中的线程在不同处理器上并行运行,缩短了运行时间
6.多核编程
- 单处理器系统发展成为多处理器系统,无论多个计算核是在多个CPU芯片上还是在单个CPU芯片上,都称为多核或多处理器系统
- 多线程编程提供机制,以便更有效地使用这些多个计算核和改进地并发性
- 并行类型
- 数据并行
- 注重将数据分布于多个计算核上,并在每个核上执行相同的操作
- 任务并行
- 将任务分配到多个计算核上,每个线程都执行一个独特的操作。不同线程可以操作相同的数据,或者也可以操作不同的数据
- 数据并行
7.Windows线程
8.Linux线程
二、多线程模型
1.用户线程
- 用户线程:由用户线程库进行管理的线程
- 内核看不到用户线程
- 用户线程的创建和调度在用户空间中,不需要内核的干预
- 应用于传统的只支持进程的操作系统
2.内核线程
- 内核线程:内核进行管理的线程
- 需要内核支持
- 由内核完成线程调度
- 由内核进行创建和撤销
3.多线程模型
多对一模型
- 不支持内核线程的操作系统
- 内核只有进程
- 内核只看到一个进程
- 缺点:多个线程不能并行运行在多个处理器上
- 进程中的用户线程由进程自己管理
- 优点:进程内线程切换不会导致进程切换
- 一个线程的系统调用会导致整个进程阻塞
一对一模型
- 用于支持线程的操作系统
- 用户线程映射到内核线程
- 操作系统管理这些线程
- 并发性好:多个线程可并发运行在多个处理器上
- 创建以一个用户线程就要创建一个相应的内核线程,内核开销大
多对多模型
- 多个用户线程映射为相等或更小数目的内核线程
- 并发性和效率兼顾
- 增加复杂度
- 双层模型:
- 多路复用多个用户级线程到同样数量或更少数量的内核线程,但也允许绑定某个用户线程到一个内核线程
- 多路复用多个用户级线程到同样数量或更少数量的内核线程,但也允许绑定某个用户线程到一个内核线程
三、线程库
1.概念
- 为程序员提供了创建和管理线程的API
- 两种模式:
- 用户库(用户线程)
- 存在于用户空间
- 不需要内核支持
- 调用线程库不会产生系统调用
- 内核库(内核线程)
- 存在于内核
- 操作系统支持
- 调用线程库会产生系统调用
- 用户库(用户线程)
- 线程创建策略
- 主线程可以不断地创建子线程;子线程自己本身有回收内存资源的能力
- 异步线程
- 一旦父线程创建了一个子线程,父线程就恢复自身的执行,这样父线程与子线程会并发执行。每个线程的运行独立于其他线程,父线程无需知道子线程何时终止,所以线程之间通常很少有数据共享
- 同步线程
- 如果父线程创建一个或多个子线程后,那么在恢复执行之前应等待所有子线程的终止(分叉-连接策略),这就出现了同步线程
- 常用线程库
- Windows线程库:内核级
- Pthreads线程库:用户级
- JAVA线程库:用户级
2.Win32线程库
- Windows操作系统支持线程技术,所以Win32线程库实际上包含在Win32 API中
- Win32线程库是内核库
- 内核线程
- 线程创建方法
- Win32 API
- MFC
- .Net Framework
- Windows线程
- 一对一映射
- 每个线程包括:
- 线程id
- 寄存器集合
- 堆栈
- 私有数据
- 线程主要的数据结构
- ETHREAD:执行线程块
- KTHREAD:核心线程块
- TEB:线程环境块
3.Pthreads线程库
- POSIX标准,可移植操作系统接口
- IEEE定义了操作系统为应用程序提供的接口标准
- 为各种Unix软件定义的一系列API标准总称为POSIX
- Pthreads:POSIX线程
- 线程的POSIX标准
- 定义了创建和管理线程的一整套API
- 常用于UNIX类操作系统
- Windows也有移植版pthreads-win32
- 一般为用户线程
4.Java线程库
- Java线程由JAVA虚拟机JVM管理
- 用户线程
- JAVA线程操作系统不可见
- 定义了创建和操纵线程的一整套API
- 跨操作系统平台
- Java线程创建
- 扩展java.lang.Thread类
- 实现Runnable接口
三、隐式线程
1.概述
- 随着进程中线程数量的增加编程越来越大困难
- 新方法:由编译器或运行库创建或管理线程
- 三种模式:
- Thread Pools
- OpenMP
- Grand Central Dispatch
2.Thread池
- 在池中创建一批线程,等到任务
- 优点:
- 利用线程池中的线程来响应请求比创建一个线程更加快速
- 允许一个应用程序中的线程数量达到线程池的上限
- 线程池限制了任何时候可用线程的数量
- 将要执行任务从创建任务的机制中分离出来,允许我们采用不同策略运行任务
3.OpenMP
- OpenMp为一组编译指令和API,用于编写C,C++,FORTRAN等语言的程序,支持共享内存环境下的并行编程
- OpenMP识别并行区间,即可并行运行的代码块
4.大中央调度(GCD)
- Apple在Mac OSX和IOS引用的技术
- C,C++,Swift,API,运行库的扩展
- 识别并行区间
- GCD提供调度队列来处理提交的任务
- 管理向GCD提交的任务并且以先进先出的顺序来执行任务
- 顺序调度队列
- 顺序队列中的任务同一时间只执行一件
- 并发调度队列
- 并发队伍中的多个任务可以并行执行
- 并发队伍中的多个任务可以并行执行