操作系统分为用户态和内核态_内核态 用户态

操作系统分为用户态和内核态_内核态 用户态这节课给你带来了一道非常经典的面试题目:用户态线程和内核态线程有什么区别?这是一个组合型的问题,由很多小问题组装而成,比如:用户态和内核态是什么?用户级线程和内核级线程是一个怎样的对应关系?内核响应系统调用是一个怎样的过程?……而且这个问题还关联到了我们后面要学习的多线程、I/O模型、网络优化等。所以这是一道很不错的面试题目,它不是简单考某个概念,而是通过让求职者比较两种东西,从而考察你对知识整体的认知和理解。今天就请你顺着这个问题,深入学习内核的工作机制,和我一起去理解用户

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

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

这节课给你带来了一道非常经典的面试题目:用户态线程和内核态线程有什么区别?

这是一个组合型的问题,由很多小问题组装而成,比如:

用户态和内核态是什么?

用户级线程和内核级线程是一个怎样的对应关系?

内核响应系统调用是一个怎样的过程?

……

而且这个问题还关联到了我们后面要学习的多线程、I/O 模型、网络优化等。 所以这是一道很不错的面试题目,它不是简单考某个概念,而是通过让求职者比较两种东西,从而考察你对知识整体的认知和理解。

今天就请你顺着这个问题,深入学习内核的工作机制,和我一起去理解用户态和内核态。

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

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

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

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

系统调用过程
如果用户态程序需要执行系统调用,就需要切换到内核态执行。下面我们来讲讲这个过程的原理。

 

操作系统分为用户态和内核态_内核态 用户态

如上图所示:内核程序执行在内核态(Kernal Mode),用户程序执行在用户态(User Mode)。当发生系统调用时,用户态的程序发起系统调用。因为系统调用中牵扯特权指令,用户态程序权限不足,因此会中断执行,也就是 Trap(Trap 是一种中断)。

发生中断后,当前 CPU 执行的程序会中断,跳转到中断处理程序。内核程序开始执行,也就是开始处理系统调用。内核处理完成后,主动触发 Trap,这样会再次发生中断,切换回用户态工作。关于中断,我们将在“15 课时”进行详细讨论。

 

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

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

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

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

一个进程可以拥有多个线程。进程创建的时候,一般会有一个主线程随着进程创建而创建。

操作系统分为用户态和内核态_内核态 用户态

如果进程想要创造更多的线程,就需要思考一件事情,这个线程创建在用户态还是内核态。

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

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

 

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

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

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

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

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

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

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

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

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

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

内核级线程有很多优势。

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

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

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

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

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

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

 

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

这时,比较常见的一种方式,就是将需要执行的程序,让一个内核线程去执行。毕竟,内核线程是真正的线程。因为它会分配到 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 性能瓶颈、思考数据库连接池的配置等,要想完美地解决问题,就必须掌握这些模型,了解问题的本质上才能更好地思考问题衍生出来的问题。

 

那么通过这节课的学习,你现在是否可以来回答本节关联的面试题目?用户态线程和内核态线程的区别?

老规矩,请你先在脑海里构思下给面试官的表述,并把你的思考写在留言区,然后再来看我接下来的分析。

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

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

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

 

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

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/192587.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • Mysql慢查询_mysql服务启动慢

    Mysql慢查询_mysql服务启动慢一、开启慢查询日志1、查看是否开启:showvariableslike’slow_query_log’;2、查看是否开启记录未使用索引的查询:showvariableslike’log_queries_not_using_indexes’;3、开启未使用索引的查询日志:setgloballog_queries_not_using_indexes=on;4、查看超过多长时间的语句才会…

    2022年10月14日
  • 【Unity3D 灵巧小知识点】 ☀️ | Unity中如何使用代码切换场景

    【Unity3D 灵巧小知识点】 ☀️ | Unity中如何使用代码切换场景Unity小科普老规矩,先介绍一下Unity的科普小知识:Unity是实时3D互动内容创作和运营平台。包括游戏开发、美术、建筑、汽车设计、影视在内的所有创作者,借助Unity将创意变成现实。Unity平台提供一整套完善的软件解决方案,可用于创作、运营和变现任何实时互动的2D和3D内容,支持平台包括手机、平板电脑、PC、游戏主机、增强现实和虚拟现实设备。也可以简单把Unity理解为一个游戏引擎,可以用来专业制作游戏!Unity小知识点学习Unity中如何使用代码切.

  • LMS波束形成

    LMS波束形成LMS自适应波束形成器%标量阵最小均方准则(LMS)自适应波束形成器(ADBF)closeall;Sound_velocity=1200;%声速Frequency=300;%信号频率Sample_Frequency=100Frequency;%采样频率Array_num=16;%阵元数Array_distance=1/2(Sound_velocity/Frequency)…

  • JavaScript 字符串截取方法汇总

    JavaScript 字符串截取方法汇总可以使用的方法及选择substring:最常见substr:不建议使用slice:最灵活JS新标准ECMAscript没有对substr进行标准化,因此不建议使用。slice比substring更灵活,允许使用负数做参数slice除了截取字符串,还可以截取数组参数和用法substring语法:stringObject.substring(start,stop)start,必需,非负整数,截取的开始位置stop,可选,非负整数,截取的字符串不包含该位置

  • 网络攻防实验之缓冲区溢出攻击

    网络攻防实验之缓冲区溢出攻击这个实验是网络攻防课程实验中的一个,但是目前我还没有完全搞懂代码,以后有机会来补。也欢迎大佬指点一、实验目的和要求通过实验掌握缓冲区溢出的原理,通过使用缓冲区溢出攻击软件模拟入侵远程主机理解缓冲区溢出危害性,并理解防范和避免缓冲区溢出攻击的措施。二、实验原理和实验环境实验原理:缓冲区溢出(BufferOverflow)是目前非常普遍而且危…

  • 阿里-中间件团队博客「建议收藏」

    阿里-中间件团队博客「建议收藏」阿里中间件团队博客地址:http://jm.taobao.org/截至2019-03-15日已发布的博客列表:2017双11专题10 2018广东云栖大会1 ACM3 AHAS1 APM1 ARMS8 AlibabaCloudToolkit1 Aliware1 ApacheRocketMQ1 BCP1 CNCF1 Docker1 Dubbo10 Dubbo…

发表回复

您的电子邮箱地址不会被公开。

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