我读了教科书(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);
我在它们的参数中找不到什么特别的东西,哪个参数是系统调用?
答案 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
,而原始系统调用为write
(fopen
与{{相同) 1}}等)。关于参数有一点特别之处,就是名称。