内核态和用户态

内核态和用户态,第1张

用户态和内核态:

*** 作系统一般有级别划分0-3,0是特权级级别最高,一般的应用程序运行在3最低级别(用户态,用户内存空间),而内核态属于0级别,有内核空间,处理一些关键性的东西比如分配内存,读写I/O,涉及TCP协议以及驱动程序等。内核态把应用程序和 *** 作系统硬件底层分离开,保障了硬件的安全性。用户的应用程序一般运行于用户态,当进行I/O读写 *** 作,网络数据发送(执行系统调用,处理中断异常,进程调度上CPU)等,会进行切换,从用户态切换到内核态,用户态进行中断,拷贝用户态信息指令等暂存到内核栈(用户态副本),内核态开始处理,处理结束切换回用户态(内核态副本清空),接着处理应用程序。

一个客户端的访问流程也不是直接请求到用户应用,数据报被缓存到内核空间,服务器端recvform首先切换到内核态,读取内核数据报复制到用户空间(网络数据存储到内核空间),然后进行调用

linux信号量运行流程:

当对一个进程进行kill *** 作时,其实相当于一个进程对另一个进程进行了信号量软中断 *** 作,也就是在另一个进程的信号表对应域做了处理,当另一个进程进行系统调用或CPU切换等 *** 作时,会从用户态转入内核态,进行副本拷贝等。处理结束切换回用户态前,会查看当前信号表是否有待处理信号,如果有,把之前内核栈保存的副本拷贝回用户态,内核态地址指向信号处理函数地址,清除内核栈,切换回用户态处理信号,处理结束重新返回内核态,压入之前的副本拷贝,查看是否还有信号量需要处理,没有的话返回地址重新指向之前的应用程序,切回用户态,清除内核态数据。

虚拟内存和物理内存:

物理内存其实就是存储的实际的数据,对应内存条,虚拟内存存的是物理内存地址,通过页管理让虚拟和物理内存产生映射,当程序编译指示给了虚拟内存建立了表,数据和程序仍然存在在磁盘,当进行运行时磁盘被有选择的加载到物理内存(物理内存不存在数据去磁盘交换)。

虚拟内存分为用户空间和内核空间(对应到物理内存对应位置),其实 *** 作虚拟内存就是类似 *** 作物理内存。

内核态相当于一个介于硬件与应用之间的层,内核有ring 0的权限,可以执行任何cpu指令,也可以引用任何内存地址,包括外围设备, 例如硬盘, 网卡,权限等级最高。

用户态则权利有限,例如在内存分配中,有一部分内存是仅为内核态使用的,用户态code则不允许访问那些内存地址,每个进程只允许访问自己申请到的内存。而且不允许访问外围设备。另外在执行cpu指令的时候也可以被高优先级抢占。

大多数时间各类程序都是执行在用户态下,毕竟内核就是基础而已。

很多博客都提到了一个状态转换的例子:c语言在malloc的时候需要涉及到从用户态到内核态的转换,malloc是个函数,所以算作系统调用,是用户态的主动申请转换。但是在实际实现中,未必一定需要进入内核态拿到新的内存,详细看这个博客: https://blog.csdn.net/zdy0_2004/article/details/47787631

3.为什么两者切换耗时

linux下每个进程的栈有两个,一个是用户态栈,一个是内核态栈。在需要从用户态栈切换到内核的时候,需要进行执行栈的转换,保存用户态的状态,包括寄存器状态,然后执行内核态 *** 作, *** 作完成后要恢复现场,切换到用户态,这个过程是耗时的。当然这里有很多细节,但是我不懂,只了解宏观上的原因。

很多人都说mutex加锁解锁很慢,为什么呢,因为他也是需要从用户态到内核态的切换,因此有一些无锁技巧例如CAS(Compare and swap),还有spin lock这种停等不作context切换的锁。

这个博客说的挺好,介绍了mutex咋切换的细节,反正我是写不出来: https://www.jianshu.com/p/5725db8f07dc

3.一些讨论

https://blog.codinghorror.com/understanding-user-and-kernel-mode/

这个博客在介绍user mode和kernel mode,但是评论里都在争论各类语言在处理exception的时候是否切换到了内核态,跑偏了

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/8724334.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-20
下一篇2023-04-20

发表评论

登录后才能评论

评论列表(0条)

    保存