Linux系统的内核态和用户态[通俗易懂]

Linux系统的内核态和用户态[通俗易懂]一、 Unix/Linux的体系架构  如上图所示,从宏观上来看,Linux操作系统的体系架构分为用户态和内核态(或者用户空间和内核)。内核从本质上看是一种软件——控制计算机的硬件资源,并提供上层应用程序运行的环境。用户态即上层应用程序的活动空间,应用程序的执行必须依托于内核提供的资源,包括CPU资源、存储资源、I/O资源等。为了使上层应用能够访问到这些资源,内核必须为上层应用提供

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

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

一、 Unix/Linux的体系架构

Linux系统的内核态和用户态[通俗易懂]

  如上图所示,从宏观上来看,Linux操作系统的体系架构分为用户态和内核态(或者用户空间和内核)。内核从本质上看是一种软件——控制计算机的硬件资源,并提供上层应用程序运行的环境。用户态即上层应用程序的活动空间,应用程序的执行必须依托于内核提供的资源,包括CPU资源、存储资源、I/O资源等。为了使上层应用能够访问到这些资源,内核必须为上层应用提供访问的接口:即系统调用。

  系统调用是操作系统的最小功能单位,这些系统调用根据不同的应用场景可以进行扩展和裁剪,现在各种版本的Unix实现都提供了不同数量的系统调用,如Linux的不同版本提供了240-260个系统调用,FreeBSD大约提供了320个(reference:UNIX环境高级编程)。我们可以把系统调用看成是一种不能再化简的操作(类似于原子操作,但是不同概念),有人把它比作一个汉字的一个“笔画”,而一个“汉字”就代表一个上层应用,我觉得这个比喻非常贴切。因此,有时候如果要实现一个完整的汉字(给某个变量分配内存空间),就必须调用很多的系统调用。如果从实现者(程序员)的角度来看,这势必会加重程序员的负担,良好的程序设计方法是:重视上层的业务逻辑操作,而尽可能避免底层复杂的实现细节。库函数正是为了将程序员从复杂的细节中解脱出来而提出的一种有效方法。它实现对系统调用的封装,将简单的业务逻辑接口呈现给用户,方便用户调用,从这个角度上看,库函数就像是组成汉字的“偏旁”。这样的一种组成方式极大增强了程序设计的灵活性,对于简单的操作,我们可以直接调用系统调用来访问资源,如“人”,对于复杂操作,我们借助于库函数来实现,如“仁”。显然,这样的库函数依据不同的标准也可以有不同的实现版本,如ISO C 标准库,POSIX标准库等。

  Shell是一个特殊的应用程序,俗称命令行,本质上是一个命令解释器,它下通系统调用,上通各种应用,通常充当着一种“胶水”的角色,来连接各个小功能程序,让不同程序能够以一个清晰的接口协同工作,从而增强各个程序的功能。同时,Shell是可编程的,它可以执行符合Shell语法的文本,这样的文本称为Shell脚本,通常短短的几行Shell脚本就可以实现一个非常大的功能,原因就是这些Shell语句通常都对系统调用做了一层封装。为了方便用户和系统交互,一般,一个Shell对应一个终端,终端是一个硬件设备,呈现给用户的是一个图形化窗口。我们可以通过这个窗口输入或者输出文本。这个文本直接传递给shell进行分析解释,然后执行。

  总结一下,用户态的应用程序可以通过三种方式来访问内核态的资源:

1)系统调用

2)库函数

3)Shell脚本

  下图是对上图的一个细分结构,从这个图上可以更进一步对内核所做的事有一个“全景式”的印象。主要表现为:向下控制硬件资源,向内管理操作系统资源:包括进程的调度和管理、内存的管理、文件系统的管理、设备驱动程序的管理以及网络资源的管理,向上则向应用程序提供系统调用的接口。从整体上来看,整个操作系统分为两层:用户态和内核态,这种分层的架构极大地提高了资源管理的可扩展性和灵活性,而且方便用户对资源的调用和集中式的管理,带来一定的安全性。

Linux系统的内核态和用户态[通俗易懂]

二、用户态和内核态的切换

  因为操作系统的资源是有限的,如果访问资源的操作过多,必然会消耗过多的资源,而且如果不对这些操作加以区分,很可能造成资源访问的冲突。所以,为了减少有限资源的访问和使用冲突,Unix/Linux的设计哲学之一就是:对不同的操作赋予不同的执行等级,就是所谓特权的概念。简单说就是有多大能力做多大的事,与系统相关的一些特别关键的操作必须由最高特权的程序来完成。Intel的X86架构的CPU提供了0到3四个特权级,数字越小,特权越高,Linux操作系统中主要采用了0和3两个特权级,分别对应的就是内核态和用户态。运行于用户态的进程可以执行的操作和访问的资源都会受到极大的限制,而运行在内核态的进程则可以执行任何操作并且在资源的使用上没有限制。很多程序开始时运行于用户态,但在执行的过程中,一些操作需要在内核权限下才能执行,这就涉及到一个从用户态切换到内核态的过程。比如C函数库中的内存分配函数malloc(),它具体是使用sbrk()系统调用来分配内存,当malloc调用sbrk()的时候就涉及一次从用户态到内核态的切换,类似的函数还有printf(),调用的是wirte()系统调用来输出字符串,等等。

Linux系统的内核态和用户态[通俗易懂]

  到底在什么情况下会发生从用户态到内核态的切换,一般存在以下三种情况:

1)当然就是系统调用:原因如上的分析。

2)异常事件: 当CPU正在执行运行在用户态的程序时,突然发生某些预先不可知的异常事件,这个时候就会触发从当前用户态执行的进程转向内核态执行相关的异常事件,典型的如缺页异常。

3)外围设备的中断:当外围设备完成用户的请求操作后,会像CPU发出中断信号,此时,CPU就会暂停执行下一条即将要执行的指令,转而去执行中断信号对应的处理程序,如果先前执行的指令是在用户态下,则自然就发生从用户态到内核态的转换。

  注意:系统调用的本质其实也是中断,相对于外围设备的硬中断,这种中断称为软中断,这是操作系统为用户特别开放的一种中断,如Linux int 80h中断。所以,从触发方式和效果上来看,这三种切换方式是完全一样的,都相当于是执行了一个中断响应的过程。但是从触发的对象来看,系统调用是进程主动请求切换的,而异常和硬中断则是被动的。

三、总结

  本文仅是从宏观的角度去理解Linux用户态和内核态的设计,并没有去深究它们的具体实现方式。从实现上来看,必须要考虑到的一点我想就是性能问题,因为用户态和内核态之间的切换也会消耗大量资源。关于实现的细节,目前学艺不精不敢乱说,等日后补上。但知道了这一点,我相信对很多问题也就很容易理解了,比如说基于缓冲区的IO和无缓冲的IO,用户进程和内核进程之间的切换,IO复用中的读写内核事件表,等等,这些知识之后会一一补上。

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

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

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

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

(0)


相关推荐

  • 锁定文件失败 未能启动虚拟机_win10无法分析无人应答文件

    锁定文件失败 未能启动虚拟机_win10无法分析无人应答文件首先看一下出现的错误:出现这个错误我也是纠结了好半天,试了网上的方法结果还是没有效果,比如下面的这个方法也不行,不知道是不是我机器的问题:后来误打误撞地把问题解决了,在创建虚拟机的最后一步将勾选的“创建后开启此虚拟机(P)”去的,即不勾选,创建完后再手动启动虚拟机,就可以了,如下图所示:…

  • docker dockerfile详解_进入docker容器命令

    docker dockerfile详解_进入docker容器命令前言Dockerfile是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。Dockerfile简介Dockerfile是用来构建Docker镜像的构建文件,是由一系列

  • transactionscope mysql_TransactionScope事务对多个数据库的操作[通俗易懂]

    transactionscope mysql_TransactionScope事务对多个数据库的操作[通俗易懂].Net2.0引入了轻量级事务管理器(LighweightTransactionManager),即System.Transactions.TransactionManager。轻量级事务管理器具有最小的开销,对比使用轻量级事务管理器的事务和直接使用本地事务,并没有性能上的差别。如果一个事务里只有一个资源管理器,轻量级事务管理器可以让资源管理器来管理该事务,而轻量级事务管理器只负责监视他;如…

  • 谷歌高级搜索技巧_谷歌搜索app技巧

    谷歌高级搜索技巧_谷歌搜索app技巧现在编程几乎就等同于谷歌了(虽然并不是什么好习惯,但很多人就是这么做的)。比如现在你想写个程序来实现某种功能,有99%的可能已经有人完成了并且把代码上传到了StackOverflow或者Github上。办公桌上已经不需要放一堆堆的参考书了,我们只需要把想知道的键入搜索框,然后期待着答案出现在前九个结果中就好了。不过很多人可能不知道,Google隐藏着许多功能强大的搜索技巧。就像掌握快捷

    2022年10月21日
  • 分布式CAP原理

    分布式CAP原理Consistentdata:    Operationscommitorfailintheirentirety(atomic)    操作的提交或者失败都是整体的(原子性)    Transactionsneverobserveorresultininconsistentdata(consistent)        事务不会导致不一致的数据  

  • ora-01007变量不在选择列表中_oracle存储过程变量赋值

    ora-01007变量不在选择列表中_oracle存储过程变量赋值使用oracle数据库过程中,偶尔遇到ORA-01008:并非所有变量都已绑定这个错误,此时应该查检sql中是否有以下情况:1、varsql=string.Format(“select*fromstudenttwheret.name=‘{0}‘andt.address=‘{1}‘”,name);此时编译不会报错,当执行sql时就会报“ORA-01008:并非所有…

发表回复

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

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