【问题标题】:system call in read and write functions读写函数中的系统调用
【发布时间】:2018-11-13 03:57:22
【问题描述】:

我读过教科书(Unix环境下的高级编程)

本章中描述的函数通常称为无缓冲 I/O,与我们在第 5 章中描述的标准 I/O 例程相反。术语无缓冲意味着每次读取或写入都会调用一个内核中的系统调用。 这些无缓冲 I/O 函数不是 ISO C 的一部分,而是 POSIX.1 和 Single UNIX 规范的一部分。

我对无缓冲一词感到困惑,意思是每次读取或写入都会调用内核中的系统调用。

读写函数是

ssize_t read(int fd, void *buf, size_t nbytes);
ssize_t write(int fd, const void *buf, size_t nbytes);

我没发现他们的参数有什么特别之处,哪个参数是系统调用?

【问题讨论】:

  • readwrite 本身是系统调用的直接调用。不要与标准 IO 例程 freadfwrite 混淆。
  • 哦,明白了,unbuffered就是手动定义BUFFSIZE。您能否转发评论以回答。 @user58697

标签: c


【解决方案1】:

系统调用很昂贵,因此标准 IO 库尽可能地推迟它们,例如通过内部缓冲输出。当它不能再缓冲时,它最终会调用一个系统调用。

此缓冲区通常与FILE 指针相关联,因此经验法则是采用FILE * 的函数进行缓冲,而采用原始int 文件描述符的函数进行系统调用。这只是一个约定,仅此而已。

Posix 命名法尝试在标准 IO 例程前加上 f,例如 fwrite,而原始系统调用是 writefopenopen 等相同)。参数有一点特别之处,就是在名字里。

【讨论】:

  • @Sawajiri 按要求。
【解决方案2】:

通常,那些系统调用。 可以想象,它们可能只是一个使用其他系统调用来完成工作的普通函数(例如,read 调用一组底层较小的操作),UNIX 及其兄弟倾向于映射一个一对一。

但无缓冲 I/O 的基本思想是不进行缓存。

当您以非缓冲方式读取和写入数据时,数据会立即发送到底层或从底层检索(系统调用暗示)。

相比之下,与 缓冲 方法相比,可以在写入之前缓存数据,或者可以读取比预期需要 更多的数据,这两者都可以提高效率。

例如看下面的(伪代码)writebuffered

def internal buffer size 1024 initially empty
def function writebuffered, accepts data:
    for each char in data:
        if internal buffer is full:
            write internal buffer
            empty internal buffer
        append char to internal buffer

你可以看到它只会在内部缓冲区已满时进行系统调用(write),从而减少整体系统调用。显然,您不会在现实生活中一次处理一个字符,但处理较大块的行为会使代码不必要地复杂化。这里的目的只是为了显示缓冲。

同样,在读取(例如,27 个字符)时,系统调用可能会获得更大的数量(例如 1K)并将其保存在预读缓冲区中以备后用,因为您可能想要阅读更多。

那么稍后读取,假设它小于或等于1K - 27 字节,就不必进行另一个系统调用来获取数据,它可以从预读缓冲区中获取它。

【讨论】:

  • reador write 是否也占用内核中的缓冲区缓存或直接写入磁盘?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-23
  • 2012-10-18
  • 2011-10-24
  • 2021-08-17
  • 2017-04-16
  • 1970-01-01
  • 2021-07-06
相关资源
最近更新 更多