概述
- 线程是CPU使用的基本单元,它由线程ID,程序计数器,寄存器集合和栈组成
- 它与属于同一进程的其他线程共享代码段、数据段和其他操作系统资源,如打开文件和信号
- 优点
- 响应度高:如果一个交互程序采用多线程,那么即使其部分阻塞或执行较冗长的操作,该程序仍能继续执行,从而增加了对用户的响应程度
- 资源共享:线程默认共享他们所属进程的内存和资源
- 经济:进程创建所需要的内存和资源的分配比较昂贵,由于线程能共享他们所属进程的资源,所以创建和切换线程会更为经济
- 多处理器体系结构的利用:能充分使用多处理器体系结构,以便每个进程能并行运行在不同的处理器上
多线程模型
- 有两种不同方法来提供线程支持:用户层的用户线程和内核层的内核线程
- 用户线程受内核线程支持,而无需内核管理
- 而内核线程由操作系统直接支持和管理
多对一模型
- 如果一个线程执行了阻塞系统调用,那么整个进程就会阻塞
一对一模型
- 将每个用户线程映射到一个内核线程
- 他提供了比上者更好的并发功能
- 唯一的缺点就是每创建一个用户线程就需要创建一个对应的内核线程
- 所以绝大多数的实现,限制了系统所支持的线程数量
多对多模型
- 当一个线程执行阻塞系统调用时,内核能调度另一个线程来执行
多线程问题
fork()
取消
- 要取消的线程称为目标线程,其取消这在如下两种情况下发生:
- **异步取消:**一个线程立即取消目标线程
- **延迟取消:**目标线程不断的检查他自己是否应该终止,这允许目标线程以有序的方式来终止自己
信号处理
- 信号是用来通知进程某个特定的时间已经发生
- 信号可以是同步或者异步接收的
- 信号是由特定事件的发生,所产生的
- 产生的信号要发送的进程
- 一旦发送,信号必须加以处理
- 同步信号是由本进程产生的
- 异步信号是由运行的进程之外的事件产生
- 发送到进程之后,进程中有多线程,那么信号发送给谁呢
- 1.发送到信号所应用的线程
- 2.发送到某些特定的线程
- 3.发送到进程中的所有线程
- 4.在进程中设置一个固定的线程,用来接收所有的信号
线程池
- 其思想就是,在在进程开始时,创建一定数量的线程,并放入到池中等待工作。
- 当服务器收到请求后,他就唤醒池中的一个线程,并将请求交付给它
- 当线程完成了请求之后,线程会再次返回池中等待工作
- 如果池中没有空闲的线程,那么服务器会一直等待,知道有空闲的出现
- 优点:
- 比等待创建新的线程,速度更快
- 线程池限制了在任何时候可用线程的数量,这对于那些不能支持高并发的系统来说非常重要。
- 线程的创建与终止
- 线程的创建在POSIX标准下接口为pthread_create(),第一个参数为pthread_t* ,指向新线程的ID,第三个参数为void ,为线程的函数入口,第二个参数为pthread_attr_t ,用来设置线程属性,第四个参数为void *,一般是个结构体,用于给新线程传递参数。
- 单个线程可以使用三种方式退出:
- 1.线程执行完毕,返回。这是最常见也是最正常的结束方式;
- 2.被其他线程结束pthread_cancel;
- 3.线程调用pthread_exit。
进程原语 | 描述 |
---|---|
fork | 创建新的控制流 |
exit | 从现有的控制流中退出 |
waitpid | 从控制流中得到退出状态 |
getpid | 获取控制流的ID |
abort | 请求控制流的非正常退出 |
进程原语 | 线程原语 |
---|---|
fork | pthread_create |
exit | pthread_exit |
waitpid | pthrad_join |
getpid | pthread_self |
abort | pthread_cancel |
抢占调度
- 1.当一个进程从运行状态切换到等待状态
- 2.当一个进程从运行状态切换到就绪状态
- 3.当一个进程从等待状态切换到就绪状态
- 4.当一个进程终止
- 当调度方案发生在2,3时,就是抢占的
调度算法
- 先到先服务调度
- 最短作业优先调度
- 优先级调度
- 多级队列调度:根据进程的属性,如内存大小,进程优先级,进程类型等,将进程永久的分配到一个队列。每个队列有自己的调度算法。
- 多级反馈队列调度:是上面的改进版。主要的思想是根据不同的CPU区间的特点,区分进程。如果进程使用过多的CPU时间,那么他会被转移到更低优先级的队列。此外,在较低优先级队列中,等待时间过长的进程,会被转移到更高优先级的队列
优先级反转
-
优先级翻转是
- 当一个高优先级任务通过信号量机制访问共享资源时,该信号量已被一低优先级任务占有,因此造成高优先级任务被许多具有较低优先级任务阻塞,实时性难以得到保证。
- 解决优先级翻转问题有优先级天花板 优先级继承 两种办法。
- 优先级天花板
- 是当任务申请某资源时, 把该任务的优先级提升到可访问这个资源的所有任务中的最高优先级, 这个优先级称为该资源的优先级天花板。
- 这种方法简单易行, 不必进行复杂的判断, 不管任务是否阻塞了高优先级任务的运行, 只要任务访问共享资源都会提升任务的优先级。
- 优先级继承
- 是当任务A 申请共享资源S 时, 如果S正在被任务C 使用,通过比较任务C 与自身的优先级,如发现任务C 的优先级小于自身的优先级, 则将任务C的优先级提升到自身的优先级, 任务C 释放资源S 后,再恢复任务C 的原优先级。
- 这种方法只在占有资源的低优先级任务阻塞了高优先级任务时才动态的改变任务的优先级
多线程同步和互斥有几种方法
-
用户模式下的方法有:原子操作(例如一个单一的全局变量),临界区。
-
内核模式下的方法有:事件,信号量,互斥量。
-
1、临界区 通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。
-
2、互斥量为协调共同对一个共享资源的单独访问而设计的。
-
3、信号量:为控制一个具有有限数量用户资源而设计。
-
4、事 件:用来通知线程有一些事件已发生,从而启动后继任务的开始。