用户态和内核态:用户态线程和内核态线程有什么区别?[通俗易懂]

用户态和内核态:用户态线程和内核态线程有什么区别?[通俗易懂]转载文章来源于拉钩教育重学操作系统林䭽用户态和内核态:用户态线程和内核态线程有什么区别?什么是用户态和内核态Kernel运行在超级权限模式(SupervisorMode)下,所以拥有很高的权限。按照权限管理的原则,多数应用程序应该运行在最小权限下。因此,很多操作系统,将内存分成了两个区域:内核空间(KernalSpace),这个空间只有内核程序可以访问;用户空间(UserSpace),这部分内存专门给应用程序使用。用户态和内核态用户空间中的代码被限制了只能使用一

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

转载

文章来源于 拉钩教育 重学操作系统 林䭽 用户态和内核态:用户态线程和内核态线程有什么区别?

什么是用户态和内核态

Kernel 运行在超级权限模式(Supervisor Mode)下,所以拥有很高的权限。按照权限管理的原则,多数应用程序应该运行在最小权限下。因此,很多操作系统,将内存分成了两个区域:

  1. 内核空间(Kernal Space),这个空间只有内核程序可以访问;

  2. 用户空间(User Space),这部分内存专门给应用程序使用。

用户态和内核态

用户空间中的代码被限制了只能使用一个局部的内存空间,我们说这些程序在用户态(User Mode) 执行。内核空间中的代码可以访问所有内存,我们称这些程序在内核态(Kernal Mode) 执行。

系统调用过程

如果用户态程序需要执行系统调用,就需要切换到内核态执行。下面我们来讲讲这个过程的原理。
在这里插入图片描述
如上图所示:内核程序执行在内核态(Kernal Mode),用户程序执行在用户态(User Mode)。当发生系统调用时,用户态的程序发起系统调用。因为系统调用中牵扯特权指令,用户态程序权限不足,因此会中断执行,也就是 Trap(Trap 是一种中断)。

发生中断后,当前 CPU 执行的程序会中断,跳转到中断处理程序。内核程序开始执行,也就是开始处理系统调用。内核处理完成后,主动触发 Trap,这样会再次发生中断,切换回用户态工作。

线程模型

上面我们学习了用户态和内核态,接下来我们从进程和线程的角度进一步思考本课时开头抛出的问题。

进程和线程

一个应用程序启动后会在内存中创建一个执行副本,这就是进程。Linux 的内核是一个 Monolithic Kernel(宏内核),因此可以看作一个进程。也就是开机的时候,磁盘的内核镜像被导入内存作为一个执行副本,成为内核进程。

进程可以分成用户态进程和内核态进程两类。用户态进程通常是应用程序的副本,内核态进程就是内核本身的进程。如果用户态进程需要申请资源,比如内存,可以通过系统调用向内核申请。

那么用户态进程如果要执行程序,是否也要向内核申请呢?

程序在现代操作系统中并不是以进程为单位在执行,而是以一种轻量级进程(Light Weighted Process),也称作线程(Thread)的形式执行。

一个进程可以拥有多个线程。进程创建的时候,一般会有一个主线程随着进程创建而创建。
在这里插入图片描述
如果进程想要创造更多的线程,就需要思考一件事情,这个线程创建在用户态还是内核态。

你可能会问,难道不是用户态的进程创建用户态的线程,内核态的进程创建内核态的线程吗?

其实不是,进程可以通过 API 创建用户态的线程,也可以通过系统调用创建内核态的线程,接下来我们说说用户态的线程和内核态的线程。

用户态线程

用户态线程也称作用户级线程(User Level Thread)。操作系统内核并不知道它的存在,它完全是在用户空间中创建。

用户级线程有很多优势,比如。

  1. 管理开销小:创建、销毁不需要系统调用。

  2. 切换成本低:用户空间程序可以自己维护,不需要走操作系统调度。

但是这种线程也有很多的缺点。

  1. 与内核协作成本高:比如这种线程完全是用户空间程序在管理,当它进行 I/O 的时候,无法利用到内核的优势,需要频繁进行用户态到内核态的切换。

  2. 线程间协作成本高:设想两个线程需要通信,通信需要 I/O,I/O 需要系统调用,因此用户态线程需要支付额外的系统调用成本。

  3. 无法利用多核优势:比如操作系统调度的仍然是这个线程所属的进程,所以无论每次一个进程有多少用户态的线程,都只能并发执行一个线程,因此一个进程的多个线程无法利用多核的优势。

  4. 操作系统无法针对线程调度进行优化:当一个进程的一个用户态线程阻塞(Block)了,操作系统无法及时发现和处理阻塞问题,它不会更换执行其他线程,从而造成资源浪费。

内核态线程

内核态线程也称作内核级线程(Kernel Level Thread)。这种线程执行在内核态,可以通过系统调用创造一个内核级线程。

内核级线程有很多优势。

  1. 可以利用多核 CPU 优势:内核拥有较高权限,因此可以在多个 CPU 核心上执行内核线程。

  2. 操作系统级优化:内核中的线程操作 I/O 不需要进行系统调用;一个内核线程阻塞了,可以立即让另一个执行。

当然内核线程也有一些缺点。

  1. 创建成本高:创建的时候需要系统调用,也就是切换到内核态。

  2. 扩展性差:由一个内核程序管理,不可能数量太多。

  3. 切换成本较高:切换的时候,也同样存在需要内核操作,需要切换内核态。

用户态线程和内核态线程之间的映射关系

线程简单理解,就是要执行一段程序。程序不会自发的执行,需要操作系统进行调度。我们思考这样一个问题,如果有一个用户态的进程,它下面有多个线程。如果这个进程想要执行下面的某一个线程,应该如何做呢?

这时,比较常见的一种方式,就是将需要执行的程序,让一个内核线程去执行。毕竟,内核线程是真正的线程。因为它会分配到 CPU 的执行资源。

如果一个进程所有的线程都要自己调度,相当于在进程的主线程中实现分时算法调度每一个线程,也就是所有线程都用操作系统分配给主线程的时间片段执行。这种做法,相当于操作系统调度进程的主线程;进程的主线程进行二级调度,调度自己内部的线程。

这样操作劣势非常明显,比如无法利用多核优势,每个线程调度分配到的时间较少,而且这种线程在阻塞场景下会直接交出整个进程的执行权限。

由此可见,用户态线程创建成本低,问题明显,不可以利用多核。内核态线程,创建成本高,可以利用多核,切换速度慢。因此通常我们会在内核中预先创建一些线程,并反复利用这些线程。这样,用户态线程和内核态线程之间就构成了下面 4 种可能的关系:

多对一(Many to One)
用户态进程中的多线程复用一个内核态线程。这样,极大地减少了创建内核态线程的成本,但是线程不可以并发。因此,这种模型现在基本上用的很少。我再多说一句,这里你可能会有疑问,比如:用户态线程怎么用内核态线程执行程序?

程序是存储在内存中的指令,用户态线程是可以准备好程序让内核态线程执行的。后面的几种方式也是利用这样的方法。
在这里插入图片描述
一对一(One to One)

该模型为每个用户态的线程分配一个单独的内核态线程,在这种情况下,每个用户态都需要通过系统调用创建一个绑定的内核线程,并附加在上面执行。 这种模型允许所有线程并发执行,能够充分利用多核优势,Windows NT 内核采取的就是这种模型。但是因为线程较多,对内核调度的压力会明显增加。
在这里插入图片描述
多对多(Many To Many)
这种模式下会为 n 个用户态线程分配 m 个内核态线程。m 通常可以小于 n。一种可行的策略是将 m 设置为核数。这种多对多的关系,减少了内核线程,同时也保证了多核心并发。Linux 目前采用的就是该模型。
在这里插入图片描述
两层设计(Two Level)
这种模型混合了多对多和一对一的特点。多数用户态线程和内核线程是 n 对 m 的关系,少量用户线程可以指定成 1 对 1 的关系。
在这里插入图片描述
上图所展现的是一个非常经典的设计。

我们这节课讲解的问题、考虑到的情况以及解决方法,将为你今后解决实际工作场景中的问题打下坚实的基础。比如处理并发问题、I/O 性能瓶颈、思考数据库连接池的配置等,要想完美地解决问题,就必须掌握这些模型,了解问题的本质上才能更好地思考问题衍生出来的问题。

用户态线程和内核态线程的区别?

用户态线程工作在用户空间,内核态线程工作在内核空间。用户态线程调度完全由进程负责,通常就是由进程的主线程负责。相当于进程主线程的延展,使用的是操作系统分配给进程主线程的时间片段。内核线程由内核维护,由操作系统调度。

用户态线程无法跨核心,一个进程的多个用户态线程不能并发,阻塞一个用户态线程会导致进程的主线程阻塞,直接交出执行权限。这些都是用户态线程的劣势。内核线程可以独立执行,操作系统会分配时间片段。因此内核态线程更完整,也称作轻量级进程。内核态线程创建成本高,切换成本高,创建太多还会给调度算法增加压力,因此不会太多。

实际操作中,往往结合两者优势,将用户态线程附着在内核态线程中执行。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/192720.html原文链接:https://javaforall.net

(0)
上一篇 2025年12月9日 下午4:15
下一篇 2025年12月9日 下午4:43


相关推荐

  • 生命游戏程序_生命游戏怎么玩

    生命游戏程序_生命游戏怎么玩引言群居性昆虫是一个生命,鱼群、鸟群是一个生命,社会、城市是一个有机体,人类的语言是活的,人类的集体行为也是活的。这些复杂系统是如何设计出来的?世界上最著名的游戏之一,GameofLife生命游戏,为这些最神秘的问题提出了可能的解释——也许再复杂的生命,最初也不过是几条最简单的规则。本文从GameofLife的缘起说起,解释了它这几十年给予数学、计算机、哲学的启发,最后把它作为P…

    2022年10月17日
    4
  • 提问的艺术,原文链接

    提问的艺术,原文链接提问的艺术

    2022年6月23日
    23
  • 实现一个域名对应多个IP地址和DNS优缺点详解!

    实现一个域名对应多个IP地址和DNS优缺点详解!实现一个域名对应多个 IP 地址和 DNS 优缺点详解 1 DNS 定义 DNS DomainNameSy 是因特网的一项服务 它作为域名和 IP 地址相互映射的一个分布式数据库 能够使人更方便的访问互联网 2 DNS 作用 1 解析域名人们在通过浏览器访问网站时只需要记住网站的域名即可 而不需要记住那些不太容易理解的 IP 地址 在 DNS 系统中有一个比较重

    2026年3月20日
    2
  • 463个生活小窍门

    463个生活小窍门1、巧用牙膏6:若有小面积皮肤损伤或烧伤、烫伤,抹上少许牙膏,可立即止血止痛,也可防止感染,疗效颇佳。2、巧除纱窗油腻3:可将洗衣粉、吸烟剩下的烟头一起放在水里,待溶解后,拿来擦玻璃窗、纱窗,效果均不错。3、将虾仁放入碗内,加一点精盐、食用碱粉,用手抓搓一会儿后用清水浸泡,然后再用清水洗净,这样能使炒出的虾仁透明如水晶,爽嫩可口。4、和饺子面的窍门1:在1斤面粉里掺入6个蛋清,使面里蛋白质增加,包的饺子下锅后蛋白质会很快凝固收缩,饺子起锅后收水快,不易粘连5、将残茶叶浸入水中数天后,浇在植

    2022年6月23日
    24
  • 曾经被你亲手敲烂过的机械键盘

    曾经被你亲手敲烂过的机械键盘一起来讲一讲程序员与键盘的故事吧

    2026年3月17日
    2
  • idea搭建vue(使用VUE打开一个项目)

    使用IDEA创建咱们的第一个VUE项目最近在学习VUE,想着使用vscode、hbulider、webstorm这些软件学习,但听前端前辈们说要很多插件什么的等等等!听完咱还是选择IDEA吧,毕竟和IDEA还是很亲近的!1.安装环境–让VUE‘顺产’(1)安装node.js至于为什么安装大家可以看看前辈们的博客哦!1.先让IDAE准备准备(迎接VUE)~~~提示:这里可以添加要学的内容例如:1、搭建Java开发环境2、掌握Java基本语法3、掌握条件语句4、掌握循环

    2022年4月14日
    299

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号