那些令人懵逼的用户态&内核态

前言

在讨论多线程时,总会不可避免地听到:线程切换损耗、上下文切换,内核态、用户态。这些专有名词还真是不好理解。因为这背后涉及的不仅仅是线程,甚至是计算机硬件与操作系统层面的内容。因此,本文的目的,只是想搞清楚用户态和内核态。

用户态与内核态

为什么会有用户态和内核态?说到底还是处于安全考虑。我们的应用程序谁都可以开发,谁都可以在操作系统中运行。如果没有一个安全机制,防止不法之徒恶意破坏,那肯定要完蛋。因此,从CPU层面就开始考虑这个事情了(这也是为什么开篇就说这是一整个计算机体系的内容)CPU分为4个等级,ring0-ring3。ring0拥有最大权限,所有资源都能控制。而ring3权限最小,我们的应用程序都是在这个权限下运行的。在这里插入图片描述
kernel也就是操作系统内核,Applications也就是应用程序。除此之外,内核有自己的专属空间,这部分地址,用户程序是不能直接访问的。
那么问题来了,如果应用程序需要请求某些资源怎么办?例如,操作硬盘上的文件?于是操作系统提供了一系列的系统调用,通过系统调用,由内核代码来执行这些操作。

进程、系统调用、上下文

进程在用户态空间有自己函数栈、内存映射表等等。而在内核空间也有对应的函数栈,用于执行内核代码函数。因此当CPU在执行进程在用户空间的代码时,我们称,进程工作在用户态。当进程在CPU上执行内核代码时,就认为进程工作在内核态。
当用户程序需要访问系统资源发起系统调用时,就需要进入内核态。所谓系统调用,就是发起一个软中断,让程序陷入内核态。关于软中断,也是计算机体系架构/操作系统的内容。这里不展开。

CPU上下文切换

进程有用户态的函数栈,也有内核态的函数栈。当陷入内核态时,就需要切换到内核态的函数栈运行。因此,这里就涉及到上下文切换。这个地方的上下文,指的是CPU上下文。就是切换CPU的程序计数器、以及一系列的寄存器。

进程上下文切换

那么当我们需要切换进程的时候,这意味着,不仅用户态的虚拟内存、函数栈等等资源,还有内核态的堆栈等等资源也需要进行切换。于是,我们不禁想:那么线程切换的时候,又干啥了呢?

线程上下文切换

要想理解线程上下文,就不得不对线程模型进行一番了解。这里大概了解一些概念:ULT、KTL、LWP。

线程模型

上面我们谈到进程有用户态的函数栈、内存空间等等,在内核态中也有这么些资源。但是这些资源,在线程中,有没有这些资源,取决于线程的实现方式。

用户级线程(n:1模型)

ULT:User Level Thread,指在用户空间对线程进行实现,内核并不知道存在线程这么个东西。换句话说,这种实现方式下,自然就没有与线程对应的内核态的资源了。因此整个进程(包括用户线程)共享进程所有的内核资源。这意味着任何一个用户线程在陷入内核态并且被阻塞时,整个进程都会被阻塞!
这个时候就需要注意了,与进程相比,线程没有内核资源。这个点将引申出后面内核线程的概念。

内核级线程(1:1模型/n:m模型)

指需要内核的参与,由内核完成线程的调度。换而言之,就是内核知道线程这个东西的存在,并对其提供支持。
而NPTL(Native POSIX Threading Library)从Linux2.6开始就被采用了。上面我们说到用户级线程没有内核空间相关资源,于是这里上了一个LWP(Light Weight Process),怎么做的呢?其实Linux对于线程也好,还是进程也罢,在内核中,都是task_struct。对于同一个进程中的所有线程作为一个分组,共享进程的虚拟内存、全局变量等,但是它有自己的函数栈。而LWP在用户态空间共享了进程的资源。
与用户线程相对的,内核线程只运行在内核态,不受用户态上下文的拖累。而它就是为LWP提供支持。

用户线程->LWP(用户态)->内核线程(内核态)

在这里插入图片描述

回到线程上下文切换,在NPTL实现下,线程上下文切换,需要切换用户态的函数栈,LWP的内核函数栈,但不需要切换进程的虚拟内存、全局变量。而在用户级线程模型的经典LinuxTreads实现下,只需要切换用户空间的资源即可。

总结

  1. 由用户程序创建的进程有内核态和用户态资源,如果一个进程只存在内核运行,则可以理解为内核进程。
  2. 用户线程,按照实现分为用户级线程、内核级线程。
  3. 内核级线程,只是说该线程有内核的支持,它并没有内核态资源。但是当LWP陷入内核态,并通过KLT对它进行支持的时候,说该线程处于内核态,倒也说的过去。

后记

如前,要搞清楚这些东西,还是得从计算机体系结构开始慢慢学习理解。文章排版可能有些乱,但内容的顺序感觉还行。各位看官,勉强看吧。。。

参考

极客时间-计算机组成原理
极客时间-趣谈Linux内核
轻量级线程(LWP)介绍以及与内核线程、用户线程的区别
Linux线程模型
CPU上下文
操作系统 | 中断 & 系统调用浅析

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值