线程的使用
使用线程的原因:
- 在许多应用中同时发生着多种活动
- 线程比进程更轻量级,比进程更容易创建,也更容易撤销
- 在性能上,如果存在大量的计算和大量的 I/O 处理,拥有多个线程会加快应用程序的执行速度
经典的线程模型
进程用于把资源集中到一起,而线程则是在 CPU 上被调度的实体。
多个线程共享一个地址空间和其他资源,多个进程共享物理内存,磁盘,打印机和其他资源。
当多线程进程在单 CPU 系统中运行时,线程轮流运行,与进程类似。
所有线程有完全一样的地址空间,也共享同样的全局变量,打开文件集,子进程等,线程之间是没有保护的。
线程有自己的堆栈,每个线程的堆栈有一帧,供各个被调用但是还没有从中返回的过程使用。
在用户空间中实现线程
有两种主要的方法实现线程包:在用户空间中和在内核中
把整个线程包放在用户空间中,内核对线程一无所知,从内核的角度考虑,为单线程进程。
优点:
- 可以在不支持线程的系统上实现
- 比陷入内核更快
- 允许每个进程有自己定制的调度算法
缺点:
- 如何实现阻塞系统调用
- 故障问题,内核不知道线程的存在,可能会阻塞整个进程,尽管其他线程是可以运行的
- 如果一个线程运行,其他线程就不能运行,除非该线程自动放弃 CPU
这种方式中,每个进程需要有其专用的线程表,用来跟踪线程。
在内核态实现线程
内核中有用来记录系统中所有线程的线程表,对线程的操作需要执行系统调用。与用户态线程相比,创建和撤销线程代价较大。但同时也避免了一些用户态线程可能出现的问题
混合实现
一种将用户级线程和内核级线程优点结合起来的方法,是使用内核级线程,然后将用户级线程与某些内核级线程多路复用起来
调度程序激活机制
调度程序激活工作的目标是模拟内核级线程的功能,但是为线程包提供通常在用户态才能实现的更好的性能和更大的灵活性。
当使用该机制时,内核给每个进程安排一定数量的虚拟处理器,并且让运行时系统将线程分配到该处理器上。该机制的基本思路是,当内核了解到一个线程被阻塞后,通知该进程的运行时系统(这里成为上行调用),运行时系统就重新调度线程,稍后,当内核知道原来的线程又可运行时,再次通知这一事件。
弹出式线程
弹出式线程指的是,一个消息的到达导致系统创建一个处理该消息的线程。
这样做的好处是,这种线程非常新,可以快速创建,消息到达与处理开始之间的时间非常短。