期末复习——线程
Posted sectumsempra
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了期末复习——线程相关的知识,希望对你有一定的参考价值。
MEMO
- 多线程下的fork():有的复制所有线程;有的仅仅复制了调用fork()的线程。
- 多线程下的exec():指定的程序会取代整个进程,包括所有线程。
多核编程
-
并发性:单核系统只有并发,
------->
-
并行性:多核同时执行
-
程序员面对的挑战:
- 识别任务:查找独立、并发的任务
- 平衡:有些任务不值得用一个单核来运行
- 数据分割
- 测试与调试
-
并行类型
- 数据并行:将数据分布于多核。
e.g.核0(0-n)、核1(n+1 - 2n)这种 - 任务并行:将线程(task任务)分布在多核上。
e.g.线程1:算数组A一行的和、线程2:算数组A一列的和
- 数据并行:将数据分布于多核。
Amdahl 定律
N核处理器,S比例为串行部分,(1-S)部分为并行部分
加速比 <= 1/(S + (1-S)/N)
线程
CPU运行调度的基本单位。
-
多线程进程内的线程私有:线程ID
- 寄存器
- 堆栈
-
多线程进程内的线程共享
- 代码段、数据段(全局变量)、打开文件列表
- 代码段、数据段(全局变量)、打开文件列表
-
多线程编程优点:响应性、资源共享、经济(创建、切换线程消耗更小)、可伸缩性
-
用户线程管理:线程库(程序员)、隐式多线程(转移管理权给编译器/运行时库)
-
内核线程管理:内核
1.多线程模型
- 多线程创建策略
- 异步线程:非阻塞,父子线程并发执行,父进程创建完就恢复执行。so很少有数据共享。
- 同步线程:阻塞,等待所有子进程终止父进程才恢复执行。
1.1多对一模型
多用户线程(一般是一个进程内的) 映射到 一个内核线程。线程调度管理都在用户空间。
每次只允许一个线程映射。
- 优:线程管理都在用户空间,效率高
- 缺:一个线程访问内核时阻塞了,整个进程都阻塞了。
一个时间段只有一个线程可以访问内核,不能并行运行在多核系统。
1.2一对一模型
一个用户线程 映射到 一个内核线程。
- 优:并发能力强,一个线程阻塞不影响其他线程。
- 缺:开销很大。所以一般会限制内核线程数量。
1.3多对多模型
也可称为双层模型。克服了前两个的缺点。
在用户线程和内核线程中间加一个数据结构--轻量级进程LWP,1个LWP与一个内核线程关联。
LWP看作一个虚拟处理器,以便程序调度运行用户线程。
- 对单核处理器
- CPU密集型程序:1个LWP即可
- I/O密集型程序:可能要多个LWP。
2.线程库
为程序员提供创建、管理线程的API。
- 实现线程库的方法
- 构建一个用户空间的函数库:非系统调用。在用户空间提供没有内核支持的库,所有代码、数据结构都在用户空间。
- 实现由OS直接支持的内核级库:代码、数据结构都位于内核空间。so每次调用API都会导致内核的系统调用。
- 3个主要线程库
- POSIX Pthreads
- Windows 头文件
#include <windows.h>
- Java
Windows和Pthreads数据共享可以直接使用全局变量,但Java没有全局变量,通过线程传递共享对象实现。
3.隐式多线程
“转移管理权”
将多线程的创建管理交给编译器and运行时库。流行趋势。
3.1线程池
- 主要思想:
- 开始时创建一定量线程,加载到线程池中等待工作。
- 有工作时唤醒线程分配任务。没有可用线程就等。
- 完成任务后,返回池中等待工作。
- 优点
- 快!:用现有的比创建新线程快
- 限制线程总数:因为有些系统不支持大量并发线程。
- 可以用不同策略执行任务:定期执行/延迟执行等等,不用考虑创建线程的问题了。更加灵活?
3.2 OpenMP 运行时库
一组编译指令API,识别并行区域 = 识别可并行运行的代码块。
- 指令
#pragma omp parallel
:有N个核创建N个线程,然后这些线程同时执行并行区域代码。#pragma omp parallel for for(;;)
:将循环工作分给多个线程。
3.3 GCD 大中央调度
Mac OS 和 iOS采用的技术。GCD为C/C++增加了块的拓展。
内部GCD线程池由POSIX线程组成。
块:^/*内容*/
- 将这些块放在调度队列上。
- 串行serial调度队列:FIFO,一次删一个,每个进程都有自己的串行队列,也叫主队列。
- 并行concurrent调度队列(我擅自改名的,书上给了并发...但是并行统一一点md垃圾翻译):FIFO,但可以一次删除多个块。
有三个系统级并发调度队列,低、默认、高优先级-->表示块重要性。
4.多线程问题
4.1 fork() exec()
- fork()可能复制所有线程/只复制调用fork()的那个
- exec()指定的程序会覆盖整个进程,包括所有线程。
4.2 信号处理
同步/异步,收到信号立即处理,只能处理一次。
- 同步信号:非法内存访问、/0问题
发送信号到同一进程 - 异步信号:Ctrl+C终止进程信号(传给所有线程)、时间片到期
发送信号给另一进程 - 信号处理程序
- 默认信号处理程序:由内核运行
- 用户定义的:
4.3 线程撤销
线程完成之前终止目标线程。两种情况
回忆一下,同步--阻塞;异步--非阻塞
- 异步撤销:另一线程直接终止目标线程
可能不会释放必要的系统资源。 - 延迟撤销:允许目标线程终止自己。目标线程不断检查是否应终止。
Pthreads线程撤销的3中模式:1.关闭(禁用线程撤销) 2.异步撤销 3.延迟撤销(默认)
4.4 TLS线程本地存储
指的是线程的自己的数据,虽然同进程内多线程共享数据段。
!TLS!=局部变量,在多个函数调用内都可见,线程特有。
4.5调度程序激活
内核线程与用户线程库之间的一种通信方案——调度器激活。
- 内核提供一组LWP给应用程序,应用程序调度用户线程到LWP
- 回调:内核将特定事件通知应用程序,由回调处理程序处理。
例如一个用户线程要阻塞时,会有回调。 - 发完回调,内核分一个新的LWP给应用程序,这个新的LWP运行回调处理程序,保存线程阻塞状态,释放LWP
- 回调处理程序调度另一个合适的线程在新LWP上运行。
- 之后阻塞结束了,再回调
5. 线程调度
- 用户线程:不可调度。由线程库管理,对OS不可见,OS可见的是用户进程
- 内核线程:可调度
内核采用SCS系统竞争范围调度 决定选择哪一个内核线程运行。
以上是关于期末复习——线程的主要内容,如果未能解决你的问题,请参考以下文章