返回介绍

底层的原理

发布于 2024-10-12 12:11:00 字数 1559 浏览 0 评论 0 收藏 0

Go 的标准库 os 提供了极其方便的封装,深入最原始的本质可以发现最核心的东西: 系统调用

Go 标准库的文件存储 IO 就是基于系统调用之上的。可以稍微跟一下 os.OpenFile 的调用:

os 库的 OpenFile 函数:

func OpenFile(name string, flag int, perm FileMode) (*File, error) {
    f, err := openFileNolog(name, flag, perm)
    if err != nil {
        return nil, err
    }
    f.appendMode = flag&O_APPEND != 0
    return f, nil
}

稍微看下 openFileNolog 函数:

func openFileNolog(name string, flag int, perm FileMode) (*File, error) {
    var r int
    for {
        var e error
        r, e = syscall.Open(name, flag|syscall.O_CLOEXEC, syscallMode(perm))
        if e == nil {
            break
        }
        if runtime.GOOS == "darwin" && e == syscall.EINTR {
            continue
        }
        return nil, &PathError{"open", name, e}
    }
    return newFile(uintptr(r), name, kindOpenFile), nil
}

可以看到 syscall.Open ,这个函数获取到一个整数,也就是在 c 语言里最常见的 fd 句柄,而 File 结构体则仅仅是基于这个的一层封装而已。

思考下,为什么会有标准库封装这一层存在?

划重点:为了屏蔽操作系统的区别 ,使用这个标准库的所有操作都是跨平台的。换句话说,如果是特殊操作系统才有的特性,那么在 os 库里就找不到对应封装的 IO 操作。

img

那么怎么使用系统调用?

直接使用 syscall 库,也就是系统调用。从名字也能看出来,系统调用是和操作系统强相关的,因为是操作系统提供的调用接口,所以系统调用会因为操作系统不同而导致不同的特性,不同的接口。

所以,如果直接使用 syscall 库来使用系统调用,那么需要自己来承受系统带来的兼容性问题。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文