2. 用户模式实现的功能

用户模式下的程序有的以库的形式存在,有的作为单独的进程运行。

系统调用

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

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

CPU的模式切换

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

内核在开始进行处理时,会验证来自进程的请求是否合理。如果请求不合理,系统调用将执行失败。

发起系统调用时的情形

通过strace命令对进程进行追踪,以了解进程究竟发起了哪些系统调用。
strace的运行结果中的每一行对应一个系统调用。

strace -o hello.log ./hello

实验

sar命令用于获取进程分别在用户模式与内核模式下运行的时间比例。
sar -P ALL 多少秒采集1次 总共采集的次数

sar -P ALL 1

  • %user和%nice:表示进程在用户模式下运行的时间比例
  • %system:cpu核心在内核模式下执行系统调用等处理所占用的时间比例
  • %idle: cpu核心完全没有运行任何处理时的空闲状态

当%system的值高达几十时,大多时陷入了系统调用发起过多,或者系统负载过高等糟糕的状态。

执行系统调用所需的时间

在strace命令后加上-T选项,就能以微秒级的精度来采集各种系统调用所消耗的实际时间。
在发现%system的值过高时,可以通过这个功能来确认到底时哪个系统调用占用了过多的系统资源。

strace -T -o hello.log ./hello

strace命令还存在其他选项

  • -tt选项能以微秒为单位来显示处理发生的时刻

系统调用的包装函数

Liunx提供了所有或者说绝大多数进程所依赖的库函数,以为编写程序提供方便。

系统调用的包装函数,不能被C语言之类的高级编程语言直接发起,只能通过与系统架构紧密连接的汇编语言代码发起。

OS提供了一些列被称为系统调用的包装函数的函数,用于在系统内部发起系统调用。

C标准库

Linux提供了C语言标准库,通常会以GNU项目提供的glibc作为C标准库使用。用C语言编写的几乎所有程序都依赖于glibc库。

Linux提供了ldd命令,用于查看程序所依赖的库。

OS提供的程序

OS提供了作为自身一部分的,用于更改OS运行方式的程序。

  • 初始化系统: init
  • 变更系统的运行方式: sysctl,nice, sync
  • 文件操作: touch, mkdir
  • 文件数据处理: grep, sort, uniq
  • 性能测试: sar, iostat
  • 编译: gcc
  • 脚本语言运行环境: perl,python,ruby
  • shell: bash
  • 视窗系统: X
posted @ 2024-07-10 13:33  Python习者  阅读(3)  评论(0)    收藏  举报