(三)系统调用

(三)系统调用

1. 概念: 操作系统对上提供服务的接口

2. 程序调用与系统调用的不同之处?

3. 开销?

一、标准C库的例子

  • 应用程序调用printf()时,会触发系统调用write()(实现在内核)。

二、系统调用

  • 操作系统服务的编程接口
  • 通常由高级语言编写(C或者C++)
  • 程序访问通常是通过高层次的API接口而不是直接进行系统调用
  • 三种最常用的应用程序编程接口(API)

    • Win32 API 用于WIndows

    • POSIX API 用于POSIX-based systems(包括UNIX,LINUX,Mac OS X)

    • Java API 用于java虚拟机(JVM)

三、系统调用的实现

  • 每个系统调用对应一个系统调用号

    • 系统调用接口根据 系统调用号 来维护表的索引

  • 系统调用 接口 调用内核态中的系统调用功能实现,并返回系统调用的状态和结果

  • 用户不需要知道系统调用的实现

    • 需要设置 调用参数 获取返回结果

    • 操作系统接口的细节大部分都隐藏在应用编程接口

      • 通过运行程序支持的库来管理

  • 系统调用

    • INT 和 IRET 指令 用于系统调用
      • 系统调用时,堆栈切换特权级转换

      • 为了保护内核的实现,这里内核用户态的应用程序之间使用不同堆栈,所以这里用一个堆栈切换,切换之后由于处于内核态,可以使用特权指令,可以直接对设备进行控制。

  • 函数调用

    为了调用一个函数需要把参数压到堆栈里,转到相应的函数去执行,执行时从堆栈里获取我的参数信息执行,执行返回的结果放在那里,再返回回来。上面函数调用里知道我相关的返回结果,然后用这个结果继续向下执行。

    • CALL 和 RET 用于常规调用

      • 常规调用 时没有 堆栈切换

四、中断、异常和系统调用的开销

系统调用比函数调用更安全,但是开销大(由于有一个用户态到内核态的切换)

  • 超过函数调用

  • 开销

    • 引导机制

    • 建立内核堆栈

    • 验证参数

    • 内核态映射到用户态的地址空间

      内核需要访问到用户态的一些信息,这些映射会导致缓存会有变化

      • 更新页面映射权限

    • 内核态独立地址空间

      • TLB(其中内容会失效)

 【1】源自《学堂在线》-清华大学 向勇, 操作系统

原文地址:https://www.cnblogs.com/douzujun/p/6435382.html