线程的概念
线程是“轻量级的进程”。
引入(多)线程作用
快速线程切换,通信易于实现,并行程度提高,减少(系统)管理开销
- 并行实体共享同一个地址空间和所有可用数据的能力。
- 线程比进程更轻量级,它们比进程更容易、更快地撤销。
- 同一进程内的线程间切换比进程间的切换要快,尤其是用户级线程间的切换。
- 拥有多个线程允许这样活动彼此重叠进行,从而会加快应用程序执行速度。
操作系统分类
- 单进程、单线程,MS-DOS 大致是这种操作系统;
- 多进程、单线程,多数 UNIX(及类 UNIX 的 LINUX) 是这种操作系统;
- 多进程、多线程,Win32(Windows NT/2000/XP 等)、Solaris 2.x 和 OS/2 都是这种操作系统;
- 单进程、多线程,VxWorks 是这种操作系统。
线程的实现方式
线程可以分为三大类:
1、内核级线程:1:1
2、用户级线程:N:1
3、混合型线程:M:N
一对一模型:该模型为每个用户级线程都设置一个内核线程与之连接,并发能力较强,但每创建一个用户线程,都需要创建一个内核线程。
多对一模型:该模型为多个用户级线程分配一个内核线程。这样的话,线程管理的开销较小,但是当一个线程在访问内核时发生阻塞,则整个进程会被阻塞。
多对多模型:多个用户线程连接到多个内核线程上,内核控制线程的数目可以根据应用和系统的不同而变化,可以比用户线程少,也可以与之相同。
内核级线程
内核级线程的实现方式,每个用户线程都直接与一个内核线程相关联
1、内核线程的创建、撤销和切换等,都是内核负责、通过系统调用完成的,即内核了解每一个作为可调度实体的线程。
2、这些线程可以在全系统内进行资源的竞争。
3、内核管理所有线程管理,并向应用程序提供API接口。
4、内核维护进程和线程的上下文。
5、以线程为基础进行调度。
6、内核空间内为每一个内核支持线程设置了一个线程控制块(PCB),内核根据该控制块,感知线程的存在,并进行控制。
7、内核线程驻留在内核空间,它们是内核对象。有了内核线程,每个用户线程被映射或绑定到一个内核线程。用户线程在其生命期内都会绑定到该内核线程。一旦用户线程终止,两个线程都将离开系统。这被称作“一对一”线程映射。
内核线程的优点:
1、多处理器系统中,内核能够调度同一进程中的多个线程并行执行。
2、不需要任何新的、非阻塞的系统调用。如果进程中的一个线程被阻塞,能够切换同一进程内的其他线程继续执行(用户级线程的一个缺点)。
3、内核还可以运行另一个进程的线程,而用户空间实现的线程中,运行时系统始终运行自己进程中的线程。
4、所有能够阻塞线程的调用都以系统调用的形式实现,代价可观。 信号是发给进程而不是线程的,当一个信号到达时,应该由哪一个线程处理它?线程可以 “注册” 它们感兴趣的信号。
内核线程的缺点:
1、内核线程数量有限。
2、如果内核线程的操作比较多,会导致上下文的开销很大。
用户级线程
在用户空间建立线程库,这个线程库里提供了一系列的针对线程的操作。这些线程的管理通过运行时系统(Run-time System)来管理的。
它的管理还是以进程为单位进行管理的,它无法感知线程的存在。因此线程间的切换不需要内核的参与,比较快。
- 用户级线程仅存在于用户空间。
- 内核并不能看到用户线程。
内核资源的分配仍然是按照进程进行分配的;各个用户线程只能在进程内进行资源竞争。
用户进程的优点:
1、可以在不支持线程的操作系统中实现;
2、线程切换速度非常快,创建和销毁线程、线程切换代价等线程管理的代价比内核线程少得多,因为保存线程状态的过程和调用程序都只是本地过程;
3、线程的调度不需要内核直接参与,控制简单;
4、具有较好的可扩展性,允许应用程序根据需要指定线程调度算法;
5、线程能够利用的表空间和堆栈空间比内核级线程多;
6、不需要陷阱,不需要上下文切换,也不需要对内存高速缓存进行刷新,使得线程调用非常快捷;
用户线程的缺点:
1、资源调度按照进程进行(内核只将处理器分配给进程),多个处理机下,同一个进程中的线程只能在同一个处理机下分时复用;
2、线程发生 I/O 或页面故障引起的阻塞时,如果调用阻塞系统调用,则内核由于不知道有线程的存在,而会阻塞整个进程从而阻塞所有线程直到磁盘 I/O 完成为止(尽管其他线程是可以运行的),因此同一进程中只能同时有一个线程在运行;
3、一个单独的进程内部,没有时钟中断,所以不可能用轮转调度的方式调度线程;
混合型线程
用户级与内核级的组合实现方式, 在这种模型中,每个内核级线程有一个可以轮流使用的用户级线程集合:
线程创建在用户空间完成,线程调度等在核心态完成。
多个用户级线程多路复用多个内核级线程。也就是说,核外的用户空间的线程通过一个机制和核内的一个内核级线程对应起来,那么调度内核的这个线程上CPU也就是调度核外的线程上的CPU。
用户级线程和内核级线程的区别
1、内核支持线程是 OS 内核可感知的,而用户级线程是 OS 内核不可感知的。
2、用户级线程的创建、撤消和调度不需要 OS 内核的支持,在语言这一级处理的;而内核支持线程的创建、撤消和调度都需 OS 内核提供支持,而且与进程的创建、撤消和调度大体是相同的。
3、用户级线程执行系统调用指令时将导致其所属进程被中断,而内核支持线程执行系统调用指令时,只导致该线程被中断。
4、在只有用户级线程的系统内,CPU 调度还是以进程为单位,处于运行状态的进程中的多个线程,由用户程序控制线程的轮换运行;在有内核支持线程的系统内,CPU 调度则以线程为单位,由 OS 的线程调度程序负责线程的调度。
5、用户级线程的程序实体是运行在用户态下的程序,而内核支持线程的程序实体则是可以运行在任何状态下的程序。