用户级线程和内核级线程,你分得清吗?

这篇文章是上一篇博客的补充,旨在把没有讲清楚的「用户级线程和内核级线程」补充完整。希望读者能对线程有更进一步的了解。



小白最近在学习多线程编程。

网上关于多线程的资料很多,小白很快就把线程的基本概念弄懂了,但关于「用户级线程和内核级线程」的概念,她却怎么也搞不清楚,只好向操作系统基础扎实的小明请教。

对于小白的问题,小明总会耐心解答:“线程里面这两个概念确实比较难理解,我先给你讲用户级线程吧。”

用户级线程

“既然你说你已经看过线程的基本概念,那我就直接跳过这一部分了。

很久很久之前,线程的概念是出现了,但操作系统厂商可不能直接就去修改操作系统的内核,因为对他们来说,稳定性是最重要的。贸然把未经验证的东西加入内核,出问题了怎么办?所以想要验证线程的可用性,得另想办法。”

“我知道我知道,那些研究人员就编写了一个关于线程的函数库,用函数库来实现线程!”小白得意的说:“这个我刚刚在网上看到了。”

“是的,他们把创建线程终止线程等功能放在了这个线程库内,用户就可以通过调用这些函数来实现所需要的功能。”小明找了张纸,写上了几个函数:pthread_creatpthread_exitpthread_joinpthread_yield ,接着说:“这是几个重要的函数,你应该能大概猜出这些函数的功能吧?”

“emmmm,让我想想,pthread_creat 是创建一个新线程,pthread_exit 是结束线程,pthread_join 嘛,我猜是准备运行某一个线程,然后把它加进就绪队列。最后一个函数我就不知道了。”

“不知道也没关系,一会你就清楚了。”小明接着讲:“要知道,刚刚我们说的线程库,是位于用户空间的,操作系统内核对这个库一无所知,所以从内核的角度看,它还是按正常的方式管理。”

小白问道:“也就是说操作系统眼里还是只有进程喽?那我用线程库写的一个多线程进程,只能一次在一个 CPU 核心上运行?”

小明点点头,说:“你说的没错,这其实是用户级线程的一个缺点,这些线程只能占用一个核,所以做不到并行加速,而且由于用户线程的透明性操作系统是不能主动切换线程的,换句话讲,如果 A,B 是同一个进程的两个线程的话, A 正在运行的时候,线程 B 想要运行的话,只能等待 A 主动放弃 CPU,也就是主动调用 pthread_yield 函数。”

tobe 注:对操作系统来说,用户级线程具有不可见性,也称透明性

“停一下,让我想一想,”小白飞速思考着小明的话,“是不是说,即使有线程库,用户级线程也做不到像进程那样的轮转调度?”

“非常正确!看来你对进程的概念很清楚嘛。不过呢,虽然不能做到轮转调度,但用户级线程也有他自己的好处——你可以为你的应用程序定制调度算法,毕竟什么时候退出线程你自己说了算。刚刚说了,因为操作系统只能看到进程的存在,那如果某一个线程阻塞了,你觉得会发生什么?”

“在操作系统眼里,是进程阻塞了,那么整个进程就会进入阻塞态,在阻塞操作结束前,这个进程都无法得到 CPU 资源。那就相当于,所有的线程都被阻塞了。”小白得意的回答。

“没错,所以如果任由线程进行阻塞操作,进程的效率将受到很大的影响,所以在这个过程中,出现了一个替代方案——jacket。所谓 jacket,就是把一个产生阻塞的系统调用转化成一个非阻塞的系统调用。”

小白惊讶地问:“这怎么做得到?该阻塞的调用,还能变得不阻塞?”

小明答道:“我来举个例子吧,不是直接调用一个系统 I/O 例程,而是调用一个应用级别的 I/O jacket 例程,这个 jacket 例程中的代码会检查并且确定 I/O 设备是不是正忙,如果忙的话,就在用户态下将该线程阻塞,然后把控制权交给另一个线程。隔一段时间后再次检查 I/O 设备。就像你说的,最后还是会执行阻塞调用,但使用 jacket 可以缩短被阻塞的时间。不过有些情况下是可以不被阻塞的,取决于具体的实现。”

小明停顿了一会,说:“用户级线程的概念大概就这么多,我们接下来讲内核级线程吧。”

内核级线程

“有了用户级线程的铺垫,内核级线程就好讲多了。现在我们知道,许多操作系统都已经支持内核级线程了。为了实现线程,内核里就需要有用来记录系统里所有线程的线程表。当需要创建一个新线程的时候,就需要进行一个系统调用,然后由操作系统进行线程表的更新。当然了,传统的进程表也还是有的。你想想看,如果操作系统「看得见」线程,有什么好处?“

小白自信的回答:“操作系统内核如果知道线程的存在,就可以像调度多个进程一样,把这些线程放在好几个 CPU 核心上,就能做到实际上的并行了。”

“还有一点你没有说到,如果线程可见,那么假如线程 A 阻塞了,与他同属一个进程的线程也不会被阻塞。这是内核级线程的绝对优势。”

“那内核级线程就没有什么缺点吗?”

“缺点当然是有的,你想想看,让操作系统进行线程调度,那意味着每次切换线程,就需要「陷入」内核态,而操作系统从用户态到内核态的转变是有开销的,所以说内核级线程切换的代价要比用户级线程大。还有很重要的一点——线程表是存放在操作系统固定的表格空间或者堆栈空间里,所以内核级线程的数量是有限的,扩展性比不上用户级线程。”

"内核级线程就这么点东西,我最后给你留一张图,你要是能看得懂,就说明你理解今天的概念了。"

小白得意地说:“我当然看得懂了,谢谢小明!”



希望你在看完我的文章之后有所收获。

感谢你的阅读,我们后会有期!

声明:原创文章,未经授权,禁止转载

原文地址:https://www.cnblogs.com/tobe98/p/11664779.html

时间: 2024-10-09 12:05:39

用户级线程和内核级线程,你分得清吗?的相关文章

操作系统--用户级线程和内核级线程

在多线程操作系统中,各个系统的实现方式并不相同.在有的系统中实现了用户级线程,有的系统中实现了内核级线程 1.内核级线程: (1)线程的创建.撤销和切换等,都需要内核直接实现,即内核了解每一个作为可调度实体的线程. (2)这些线程可以在全系统内进行资源的竞争. (3)内核空间内为每一个内核支持线程设置了一个线程控制块(TCB),内核根据该控制块,感知线程的存在,并进行控制. 在一定程度上类似于进程,只是创建.调度的开销要比进程小.有的统计是1:10 2.用户级线程: (1)用户级线程仅存在于用户

操作系统: 用户级线程和内核级线程

1 .内核级线程:切换由内核控制,当线程进行切换的时候,由用户态转化为内核态.切换完毕要从内核态返回用户态:可以很好的利用smp,即利用多核cpu.windows线程就是这样的. 2. 用户级线程内核的切换由用户态程序自己控制内核切换,不需要内核干涉,少了进出内核态的消耗,但不能很好的利用多核Cpu,目前Linux pthread大体是这么做的. 线程的实现可以分为两类:用户级线程(User-Level Thread)和内核线线程(Kernel-Level Thread),后者又称为内核支持的线

用户级线程和内核级线程的区别

转载于http://col1.blog.163.com/blog/static/1909775192012719114033352/ 1 .内核级线程:切换由内核控制,当线程进行切换的时候,由用户态转化为内核态.切换完毕要从内核态返回用户态:可以很好的利用smp,即利用多核cpu.windows线程就是这样的. 2. 用户级线程内核的切换由用户态程序自己控制内核切换,不需要内核干涉,少了进出内核态的消耗,但不能很好的利用多核Cpu,目前Linux pthread大体是这么做的. 线程的实现可以分

多线程 用户级线程和内核级线程 from C++多核高级编程

转 http://book.51cto.com/art/201006/206946.htm 6.1.1 用户级线程和内核级线程 2010-06-21 20:37 齐宁/董泽惠 译 清华大学出版社 字号:T | T <C++多核高级编程>第6章多线程,本章将介绍:什么是线程; 用于线程管理的pthread API;线程调度及优先级;线程竞争范围;扩展thread_object以封装线程属性功能.本节为大家介绍用户级线程和内核级线程. AD: 6.1.1  用户级线程和内核级线程 线程有3种实现模

(转)用户级和内核级线程

转:http://book.51cto.com/art/201006/206946.htm 6.1.1  用户级线程和内核级线程 线程有3种实现模型: 用户级或应用程序级线程 内核级线程 用户级和内核级混合线程 图6-1显示了3种线程实现模型.图6-1(a)显示了用户级线程,图6-1(b)显示了内核级线程,图6-1(c)则显示了用户线程和内核线程的混合.   (点击查看大图)(a) 用户级线程   (点击查看大图)(b) 内核级线程图6-1   (点击查看大图)(c) 混合线程图6-1(续) 这

内核级线程与用户级线程

这两天在写这篇blog的时候,顺带复习操作系统的资料,遇到了一个之前没有弄明白的问题,就是关于内核级线程与用户级线程.在查阅了一些资料之后,发表一下我个人简介. 线程已经在许多系统中实现,到那时各个操作系统实现方式不完全相同. 比如在有的系统中,特倍是一些数据库管理系统如IBM的infomix系统,所实现的用户级线程(UserLevel Threads ,ULT):而另一些系统如(Mac os的前身Macintosh和OS/2操作系统)所实现的是内核支持线程 ( Kernel Supported

线程的实现方式之内核支持线程和用户级线程

线程是OS进行独立调试.执行的基本单位,进程是系统进行资源分配的基本单位,一个进程可以包含若干个线程.无论是系统进程还是用户进程,进程的创建.撤消.以及要求系统设备完成的IO操作,都是利用系统调用而进入内核,再由内核中相应处理程序予以完成.进程的切换同样是在内核的支持下实现的.即不论什么样的进程,它们都是在OS内核的支持下运行的,是与内核紧密相关的. 1. 线程的分类 线程根据其实现方式不同又可分为内核支持线程KST(Kernel Supported Threads).用户级线程ULT(User

线程的3种实现方式--内核级线程, 用户级线程和混合型线程

之前降解过内核线程.轻量级进程.用户线程三种线程概念解惑(线程≠轻量级进程), 但是一直对其中提到的线程的实现模型比较迷惑, 这次就花了点时间怎么学习了一下子 1 线程的3种实现方式 在传统的操作系统中,拥有资源和独立调度的基本单位都是进程.在引入线程的操作系统中,线程是独立调度的基本单位,进程是资源拥有的基本单位.在同一进程中,线程的切换不会引起进程切换.在不同进程中进行线程切换,如从一个进程内的线程切换到另一个进程中的线程时,会引起进程切换 根据操作系统内核是否对线程可感知,可以把线程分为内

内核级线程(KLT)和用户级线程(ULT)

内核级线程(KLT)和用户级线程(ULT) tags: KLT ULT 内核级线程 用户级线程 引言:本文涉及到操作系统的内核模式和用户模式,如果不太懂的话,可以参看我的这篇文章内核模式和用户模式,其中简单的进行了介绍. 进程和线程 首先说一下线程对于进程的优势,这其实就是线程出现的意义. 进程是资源拥有的基本单位,进程切换需要保存进程状态,会造成资源的消耗.同一进程中的线程,共享进程获取的部分资源.在同一进程中,线程的切换不会引起进程切换,线程的切换需要的资源少于进程切换,可以提高效率. 内核