读写函数中的系统调用



我读过课本(Unix环境下的高级编程(

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

我与混淆了术语unbuffered意味着每次读取或写入都会调用内核中的系统调用

读写功能是

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

我在他们的参数中找不到任何特别的东西,哪个参数是系统调用?

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

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

Posix命名法试图用f作为标准IO例程的前缀,例如fwrite,而原始系统调用是write(与fopenopen等相同(。参数有一点特别,它在一个名称中。

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

最新更新