读写功能中的系统调用

时间:2018-11-13 03:57:23

标签: c

我读了教科书(Unix环境中的高级编程)

  

与我们在第5章中描述的标准I / O例程相比,本章中描述的功能通常称为无缓冲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);

我在它们的参数中找不到什么特别的东西,哪个参数是系统调用?

2 个答案:

答案 0 :(得分:1)

通常,这些系统调用。 可以想象,它们可能只是使用其他系统调用来完成工作的普通函数(例如,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个字节,则无需进行另一个系统调用来获取数据,只需从预读缓冲区中获取数据即可。

答案 1 :(得分:1)

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

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

Posix命名法尝试用f为标准IO例程加上前缀,例如fwrite,而原始系统调用为writefopen与{{相同) 1}}等)。关于参数有一点特别之处,就是名称。