返回介绍

系统调用

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

系统调用在 syscall 里有一层最基础的封装:

文件 Open

func Open(path string, mode int, perm uint32) (fd int, err error) 

文件 Read

func Read(fd int, p []byte) (n int, err error) func Pread(fd int, p []byte, offset int64) (n int, err error) 

文件读有两个接口,一个 Read 是从 当前默认偏移 读一个 buffer 数据, Pread 接口则是从指定位置读数据的接口。

思考一个问题: Pread 从效果上来讲等于 SeekRead 组合起来使用,那么是否可以认为 Pread 就可以被 Seek + Read 替代呢?

不行!根本原因在于 Seek + Read 是在用户层就是两步操作,而 Pread 虽然是 Seek + Read 的效果,但是操作系统给到用户的语义是: Pread 是一个原子操作。还有一个重要区别, Pread 不会改变当前文件的偏移量(普通的 Read 调用会更新偏移量)。

所以,总结下,**Pread** 和顺序调用 **Seek** 后调用 **Read** 有两点重要区别:

  1. Pread 对用户提供的语义是原子操作,在调用 Pread 时,无法中断 SeekRead 操作;
  2. Pread 调用不会更新当前文件偏移量;

文件 Write

func Write(fd int, p []byte) (n int, err error) func Pwrite(fd int, p []byte, offset int64) (n int, err error) 

文件写对应也是有两种接口, WrtiePwrite 分别是对应 ReadPread 。同样的, Pwrite 作用上也是相当于先调用 Seek 再调用 Write ,但是同样的也有 两点不同

  1. Pwrite 完成 SeekWrite 对外是原子操作的语义;
  2. Pwrite 调用不会更新当前文件偏移量;

文件 Seek

func Seek(fd int, offset int64, whence int) (off int64, err error) 

这个函数调用允许用户指定偏移(这个会影响到 ReadWrite 读写的位置)。一般来说,每个打开文件都有一个相关联的“当前文件偏移量”( current file offset )。读( Read )、写( Write )操作都是从 当前文件偏移量处 开始,并且 ReadWrite 会导致偏移量增加,增加量就是所读写的字节数。

小结一下 :Go 核心的 Open,Read,Write,Seek 几个系统调用,可以发现一个明显不同与标准 IO 库的区别: 系统调用操作对象是一个整数句柄Open 文件得到一个整数 fd,之后的所有 IO 都是针对这个 fd 来操作的。这个明显和标准库不同,os 标准库 OpenFile 得到的是一个 File 结构体,所有的 IO 也是针对这个结构体的。

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

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

发布评论

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