系统调用:计算机中的“服务员”

开发 架构
操作系统是基础软件,与其它软件是不同的进程。其它软件使用操作系统提供的能力,可以用进程间通信,但是各种进程间通信机制也是基于系统调用,所以直接使用系统调用更为便捷。

一、什么是系统调用

想象一下,你在一家餐厅就餐,你需要通过服务员来点菜、支付等。系统调用就像是这个服务员,它在软件和操作系统之间起到了桥梁的作用。当软件需要操作系统提供的某项服务时,它就像顾客一样,通过点菜(调用API)来告诉服务员(系统调用)它的需求。本质上,系统调用就是用户程序与操作系统之间的接口程序。

二、为什么需要系统调用

保护资源

就像在餐厅里,你不能直接进厨房做饭,而需要通过服务员来点菜。同样,操作系统会将可能产生多个程序访问冲突的资源保护起来,提供API,软件只能通过系统调用这些API来操作对应的资源。比如应用程序要访问网络、读写文件等都需要通过系统调用来完成。

简化软件开发

就像你只需要告诉服务员你想吃什么,而不需要自己去厨房做饭。操作系统为简化上层软件开发,对某些资源和基础能力进行封装,提供API,软件通过系统调用这些API可以轻松集成能力。

操作系统是基础软件

操作系统是基础软件,与其它软件是不同的进程。其它软件使用操作系统提供的能力,可以用进程间通信,但是各种进程间通信机制也是基于系统调用,所以直接使用系统调用更为便捷。

三、系统调用过程

系统调用和普通库函数调用非常相似,只是系统调用由操作系统内核提供,运行于内核态,而普通的库函数调用由函数库或用户自己提供,运行于用户态。

图片图片

软中断模式

在软中断模式下,用户程序会调用标准库,这就像顾客看菜单点菜。然后,标准库执行软中断指令,CPU切换上下文,由用户态进入内核态,这就像服务员把菜单带到厨房。内核通过中断向量表查找到中断处理程序,并执行它,这就像厨师根据菜单开始做菜。系统调用执行完毕,从中断处理程序返回,这就像服务员把做好的菜端给顾客。

在软中断模式中,CPU只需要执行一个INT指令就可以了,比较简单。

快速调用

快速调用是为了避免上下文切换的开销。这就像顾客直接告诉厨师他们想吃什么,而不需要通过服务员,使得通信的速度更快,更有效率。

快速调用需要CPU的支持,以x86 CPU为例,快速调用的实现主要使用了两个指令:sysenter和sysexit。

sysenter指令

sysenter指令是一个特殊的CPU指令,它用于从用户态切换到内核态。当一个程序需要进行系统调用时,它会执行sysenter指令。这个指令会使CPU切换到内核态,并跳转到操作系统内核中预设的系统调用入口点。这个过程中,CPU不需要执行中断,也不需要切换上下文,因此,执行sysenter指令的开销比执行软中断的开销要小。

sysexit指令

与sysenter指令相对应,sysexit指令用于从内核态切换回用户态。当系统调用完成后,操作系统内核会执行sysexit指令。这个指令会使CPU切换回用户态,并跳转回到执行sysenter指令之后的下一条指令。这个过程同样不需要执行中断和切换堆栈,因此,执行sysexit指令的开销也比执行软中断的开销要小。

不同的CPU可能会有不同的快速调用方式,不过应用程序不需要关心CPU具体是怎么做的,操作系统会做好封装,标准库会提供操作的API。

四、代码示例

在Go语言中,我们可以使用syscall包来进行系统调用。下面是一个使用syscall包进行系统调用的示例,该示例使用系统调用获取系统时间:

package main

import (
    "fmt"
    "syscall"
    "time"
)

func main() {
    // 创建一个syscall.Timeval结构体用于存储时间
    var tv syscall.Timeval

    // 使用syscall.Gettimeofday函数获取当前时间
    err := syscall.Gettimeofday(&tv)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }

    // 将秒和微秒转换为time.Time类型
    t := time.Unix(tv.Sec, tv.Usec*1000)

    // 打印时间
    fmt.Println("Current time:", t)
}

在这个示例中,我们首先创建了一个syscall.Timeval结构体用于存储时间。然后,我们使用syscall.Gettimeofday函数来获取当前时间,并将其存储在我们之前创建的syscall.Timeval结构体中。最后,我们将syscall.Timeval中的秒和微秒转换为time.Time类型,并打印出来。

责任编辑:武晓燕 来源: 萤火架构
相关推荐

2023-10-11 18:30:39

Web系统程序

2021-01-22 05:44:24

数据底层架构

2011-07-05 13:11:45

2018-08-24 10:35:49

物理内存存储

2009-06-25 09:01:42

Linux

2016-12-12 09:39:40

2012-12-20 09:42:16

Linux超级计算机HPC

2021-02-01 06:41:47

流水线计算机队列

2013-02-27 14:31:17

Windows Ser

2021-02-03 05:25:39

存储层次化代码

2021-04-15 18:09:14

存储程序计算机

2020-11-06 09:19:20

应用编译源代码

2014-04-10 09:40:51

System 360计算机计算机系统

2012-04-16 14:58:42

2018-07-05 09:25:07

系统存储层次

2023-01-27 20:02:24

数值字符串二进制

2015-09-30 11:22:19

计算机大数据

2011-05-11 09:42:27

程序员

2022-03-30 15:25:28

链接过程计算机系统程序

2023-03-02 07:49:38

点赞
收藏

51CTO技术栈公众号