#操作系统概念阅读笔记4 ##线程
###线程概念
- 线程是CPU使用的基本单元,它由线程ID 程序计数器 寄存器集合和栈的组成。
- 单线程进程与多线程进程的差别
###线程产生的动机
- 一个应用程序可能需要执行多个相似任务
- 在远程过程调用(RPC)系统中,线程可以起到很重要的作用。(多线程通信等)
###多线程编程的优点
- 响应度高
- 资源共享
- 经济
- 多处理器体系结构利用
###多线程模型 有两种不同的方法来提供线程支持:用户层的用户线程或内核层的内核线程。用户线程受内核支持,而无须内核管理;而内核线程由操作系统直接支持和管理
####多对一模型 将许多用户级线程映射到一个内核线程。线程管理是由线程库在用户空间进行的,因而效率比较高。但是如果一个线程执行了阻塞系统调用,那么整个进程会阻塞。而且,因为任一时刻只有一个线程能访问内核,多个线程不能并行运行在多处理器上。(每次只能调度一个线程,并没有增加并发性)
####一对一模型 把每个用户线程映射到一个内核线程。一个线程执行阻塞时,其余线程一般可以正常运行。它也允许多个线程能并行地运行在多处理器系统上。缺点就是 每个线程都需要一个相应的内核线程。由于创建内核线程的开销会影响应用程序的性能,即会限制系统所支持的线程数量。
####多对多模型 多路复用许多用户线程到同样数量或更小数量的内核线程上。优点:开发人员可以创建任意多的用户线程,并且相应内核线程能在多处理器系统上并发执行。而且,当一个线程执行阻塞系统调用时,内核能调度另一个线程来执行 一个流行的变种是,在基础多对多模型的同时,也允许将一个用户线程绑定到某个内核线程上。--二级模型
###线程库 线程库为程序员提供创建和管理线程的API
- 在用户空间中提供一个内有内核支持的库,此库的所有代码和数据结构都存在于用户空间中,调用库中的一个函数只是导致了用户空间中的一个本地函数调用,而不是系统调用。
- 执行一个由操作系统直接支持的内核级的库,库的代码和数据结构存在于内核空间中。调用库中的一个API函数通常会导致对内核的系统调用。 主要线程库:1.POSIX Pthread 2.Win32 3.Java
###多线程问题 ####fork()问题
- 如果fork()后 立即调用exec()就没有必要复制所有线程
- fork()之后不调用exec(),则应复制所有线程
####线程取消 线程取消是在线程完成之前来终止线程的任务。要取消的线程通常称为目标线程。
- 异步取消:一个线程立即终止目标线程
- 延迟取消:目标线程不断地检测它是否应终止,这允许目标线程有机会以有序方式来终止自己
####信号处理 信号处理的过程:1.信号是由特定事件的发生所产生的。 2.产生的信号要发送到进程 3一旦发送,信号必须加以处理。
- 同步信号:非法访问内存或被0所除等。同步信号发送到执行操作而产生信号的同一进程,
- 异步信号:使用特殊键(ctrl+c)或定时器到期等 当一个信号由允许进场之外的事件产生,那么进程就异步接受这一信号。通常异步信号被发送到另一个进程。
信号处理程序:1.默认信号处理程序2.用户定义的信号处理程序
多线程进程信号处理选择:
- 发送信号到信号所应用线程
- 发送信号到进程内到每个线程
- 发送信号到进程内到某些固定线程
- 规定一个特定线程以接受进程的所有信号
线程池
产生原因: 多线程服务器存在一些潜在问题
- 关于在处理请求之前用以创建线程的事件,以及线程在完成工作之后要被丢弃这一事实
- 如果允许所有并发请求都通过新线程来处理,那么将没法限制在系统中并发执行的线程的数量。而无限制的线程会耗尽系统资源
所以 线程池应运而生,在进程开始时创建一定数量的线程,并放入池中待命。若有请求,就唤醒。执行完毕,再放入池中。如果请求时,无可用线程,就等待有空线程出现。
优点:
- 通常用现有线程处理请求要比等待创建新的线程要快
- 线程池限制了在任何时候可用线程的数量,不会耗尽系统资源
内核于线程库之间通信问题
对于用户线程库,LWP表现为一种应用程序可以调度用户线程来运行的虚拟处理器。每个LWP与内核线程相连,该内核线程被系统调度到物理处理器上运行。如果内核线程阻塞,LWP也阻塞,与LWP相连的用户线程也阻塞。
典型题目
##4.1
举两个多线程程序设计的例子来说明多线程不比单线程方案提高性能
1)任何形式的顺序程序对线程来说都不是一个好的形式。例如一个计算个人报酬的程序或计算时间流逝。
2)另外一个例子是一个“空壳”程序,如C-shell和korn shell。这种程序必须密切检测其本身的工作空间。如打开的文件、环境变量和当前工作目录
3)能用单线程完美解决的所有问题
4.2
描述一下线程库采取行动进行用户级线程上下文切换的过程
答:用户线程之间的上下文切换和内核线程之间的相互转换是非常相似的。但它依赖于线程库和怎样把用户线程指给内核程序。一般来说,用户线程之间的上下文切换涉及到用一个用户程序的轻量级进程(LWP)和用另外一个线程来代替。这种行为通常涉及到寄存器的节约和释放。
##4.8
考虑一个多处理器系统和用多线程对多线程模式编写的多线程程序。让程序中的用户线程数量多于系统中的处理器的数量,讨论下列情况下的性能意义:
- 由程序分配的内核线程的数量比处理器少 当内核线程的数量少于处理器时,一些处理器将仍处于空闲状态。较单线程来说,对多核处理器利用率更高
b. 由程序分配的内核线程的数量与处理器相同
所有处理器将同时使用。当一个内核块内的内核(因页面错误或同时调用系统调用)相应的处理器将闲置。利用率高
c. 由程序分配的内核线程的数量大于处理器数量但少于用户线程的数量
它会定时封锁一个内核线程并调出,换入另一个准备执行的内核线程。利用率高,稳定性稍差