用户级线程与核心级线程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_39138071/article/details/80231760
1、用户级线程
把整个线程实现部分放在用户空间中,内核对线程一无所知,内核看到的就是一个单线程进程。 只有一个用户栈

优点:
1)整个用户级线程的切换发生在用户空间,这样的线程切换至少比陷入内核要快一个数量级(不需要陷入内核、不需要上下文切换、不需要对内存高速缓存进行刷新,这就使得线程调度非常快捷)
2)用户级线程有比较好的可扩展性,线程能够利用的表空间和堆栈空间比内核级线程多,这是因为在内核空间中内核线程需要一些固定的表格空间和堆栈空间,如果内核线程的数量非常大,就会出现问题。
3)可以在不支持线程的操作系统中实现。
4)创建和销毁线程、线程切换代价等线程管理的代价比内核线程少得多, 因为保存线程状态的过程和调用程序都只是本地过程
5)允许每个进程定制自己的调度算法,线程管理比较灵活。这就是必须自己写管理程序,与内核线程的区别
6)线程的调度不需要内核直接参与,控制简单。
缺点:
1)一个线程阻塞,会阻塞该进程中其他所有的线程(具体,举个例子)
比如:线程发生I/O或页面故障引起的阻塞时,如果调用阻塞系统调用则内核由于不知道有多线程的存在,而会阻塞整个进程从而阻塞所有线程
页面失效也会产生类似的问题。
2)如果一个线程开始运行,那么该进程中其他线程就不能运行,除非第一个线程自动放弃CPU。因为在一个单独的进程内部,没有时钟中断,所以不能用轮转调度(轮流)的方式调度线程
2、核心级线程
在内核中有一个用来记录系统中所有线程的线程表(TCB,进程表PCB),当某个线程希望创建一个新线程或撤销一个已有线程时,它进行一个系统调用,这个系统调用通过对线程表的更新完成线程的创建或撤销工作。
一个用户栈,一个内核栈,分别保存在用户空间和内核空间,TCB切换发生在内核空间,TCB切换会造成这两个栈的切换

优点:
1)当一个线程阻塞时,内核根据选择,可以运行同一个进程或其他进程
缺点:
1)在内核中创建和撤销线程的开销比较大,速度慢
3、用户级、核心级线程相结合:

在一些系统中,使用组合方式的多线程实现, 线程创建完全在用户空间中完成,线程的调度和同步也在应用程序中进行. 一个应用程序中的多个用户级线程被映射到一些(小于或等于用户级线程的数目)内核级线程上。

下图说明了用户级与内核级的组合实现方式, 在这种模型中,每个内核级线程有一个可以轮流使用的用户级线程集合

平时我们使用的pthread线程库就是一个组合方式的多线程


4、用户级、核心级线程优缺点、区别:
1)内核支持线程是 OS 内核可感知的,而用户级线程是 OS 内核不可感知的。
2) 用户级线程的创建、撤消和调度不需要 OS 内核的支持,是在语言(如 Java )这一级处理的;而内核支持线程的创建、撤消和调度都需 OS 内核提供支持,而且与进程的创建、撤消和调度大体是相同的。
3)用户级线程执行系统调用指令时将导致其所属进程被中断,而内核支持线程执行系统调用指令时,只导致该线程被中断。
4)在只有用户级线程的系统内, CPU 调度还是以进程为单位,处于运行状态的进程中的多个线程,由用户程序控制线程的轮换运行;在有内核支持线程的系统内, CPU 调度则以线程为单位,由 OS 的线程调度程序负责线程的调度。
5) 用户级线程的程序实体是运行在用户态下的程序,而内核支持线程的程序实体则是可以运行在任何状态下的程序。
5、当一个多线程进程创建新的进程时面临的问题:
1)子进程是否继承所有的线程;
2)信号是发给进程而不是线程的,那么当一个信号到达时,由那个线程来处理,线程可以“注册”它们感兴趣的信号

参考书籍:《现代操作系统》

一个介绍比较详细的博客:https://blog.csdn.net/gatieme/article/details/51892437


猜你喜欢

转载自blog.csdn.net/weixin_39138071/article/details/80231760