LINUX学习:用户模式和内核模式

92 阅读3分钟

个人Github地址 github.com/AmbitionTn/… , 希望下面的文章对大家有所帮助,要是觉得感兴趣可以关注一下,会持续更新,持续学习中

读书记录:LINUX是怎样工作的

计算机系统硬件结构

image.png

在计算机系统运行时,在硬件设备上会重复以下步骤

  • 通过输入输出设备或网络适配器,向计算机发送请求。
  • 读取内存中命令,并在CPU上执行,把结果写入负责保存数据的内存区域中
  • 将内存中的数据写入HDD,SDD等
  • 重复步骤1

进程是如何与设备交互的

image.png

  • CPU存在内核模式与用户模式两种模式,LINUX为了减少开发人员对于设备的调用都要写重复的调用的逻辑,提供了设备驱动器,所有的设备的交互都是通过设备驱动器做的,同时为了避免进程直接调用设备,对于设备的调用必须是内核模式做的。

  • 用户模式与内核模式交互是通过系统调用完成的。

进程与OS的关系

image.png

一般来说,用用户模式下运行的进程通过系统调用向内核发送相应的请求,其中存在进程独有的代码、三方库,也存在OS提供的库。

系统调用

进程在执行创建进程、操控硬件等依赖于内核处理时,必须通过系统调用向内核发送请求。系统调用的种类如下

  • 进程控制(创建和删除)
  • 内存管理(分配和释放)
  • 进程间通信
  • 网络管理
  • 文件系统操作
  • 文件操作(访问设备)

CPU的模式切换

image.png 系统调用通过执行特殊的CPU命令来发起。通常进程运行在用户模式下,当通过系统调用向内核发送请求时,CPU会发生名为中断的事件。这时,CPU将从用户模式切换到内核模式,然后根据请求内容进行相应的处理。当内核完成系统调用户,会重新回到用户模式,继续运行进程。

内核在开始的处理时验证来自进程的请求是否合理(例如请求内存量是否大于系统所需的内存量)。如果请求不合理,系统调用将会执行失败。

并不存在用户进程绕过系统调用而直接切换CPU运行模式的方法

实验

strace命令

下面使用Go程序编写Hello world 来看一下系统调用的场景

package main

import "fmt"

func main() {
    fmt.Println("Hello world")
}

使用strace查看系统调用情况,strace -o 输出到文件

strace -o hello.log ./hello

image.png

可以关注一下箭头这里,发生系统调用,调用Write打印到屏幕上。

sar命令

sar命令用于获取进程分别在用户模式与内核模式下运行的时间比例。

sar -P ALL 1 3

image.png

  • 可以写一个循环程序,看一下CPU用户模式和内核模式的时间占比,以及写一个循环系统调用,看下占比情况。

总结

通过理解计算机结构以及进程是如何与内核交互的。当在进程中我们写一个循环、写一个系统调用、或是一个打印字符串的语句,到底经历了哪些步骤才完成交互的。通过这个过程的理解,对于后续的程序开发能够更加清楚运行情况,做到更多的思考和优化。

下面是这篇文章的一些和核心点:

  • 进程与内核交互必须通过系统调用发送中断信号才可以,不能够直接切换CPU模式
  • 对于设备操作、文件操作、进程控制、网络管理等都是内核模式处理的。
  • 用户模式不能直接操作内核