线程的实现方式
用户线程
用户线程的管理无需内核的支持。
内核线程
内核线程由操作系统来直接支持与管理。内核线程从来不会访问属于用户态虚拟地址空间,这种线程只在内核虚拟地址空间范围活动。
用户线程和内核线程必然有联系
多线程模型
多对一模型
一个进程里的多个用户线程映射到一个内核线程。这种模型下,线程管理由用户空间的线程库来完成。
优点
- 可以在不支持线程的操作系统中实现。
- 创建和销毁线程、线程切换代价等线程管理的代价比内核线程少得多, 因为保存线程状态的过程和调用程序都只是本地过程
- 允许每个进程定制自己的调度算法,线程管理比较灵活。这就是必须自己写管理程序,与内核线程的区别
- 线程能够利用的表空间和堆栈空间比内核级线程多
- 不需要陷阱,不需要上下文切换,也不需要对内存高速缓存进行刷新,使得线程调用非常快捷
- 线程的调度不需要内核直接参与,控制简单。
缺点
- 线程发生I/O或页面故障引起的阻塞时,如果调用阻塞的系统调用,则内核由于不知道有多线程的存在,会阻塞整个进程从而阻塞所有线程。
页面失效也会产生类似的问题。 - 一个单独的进程内部,没有时钟中断,所以不可能用轮转调度的方式调度线程
- 资源调度按照进程进行,多个处理机下,同一个进程中的线程只能在同一个处理机下分时复用。这是因为从内核的角度看,只能看到一个进程,而看不到进程里的多线程。
一对一模型
映射每个用户线程到一个内核线程。
优点
- 在多处理器系统中,内核能够同时调度同一个进程中的多个线程并行执行;
- 如果进程中一个线程执行阻塞系统调用时,能够允许另一个线程继续执行,提供了比多对一模型更好的并发性能。
缺点
创建一个用户线程就要创建一个相应的内核线程。由于创建内核线程的开销会影响应用程序的性能,所以这种模型的大多数实现限制了系统支持的线程数量。
补充
Linux,还有Windows操作系统的家族,都实现了一对一模型。
多对多模型
轻量级进程
轻量级进程就是有单独的一个内核线程支持的用户线程。即一个用户线程映射一个内核线程 (一对一)。
与普通进程区别:LWP只有一个最小的执行上下文和调度程序所需的统计信息。
- 处理器竞争:因与特定内核线程关联,因此可以在全系统范围内竞争处理器资源
- 使用资源:与父进程共享进程地址空间
- 调度:像普通进程一样调度
即使有一个LWP在系统调用中阻塞,也不会影响整个进程的执行。