【问题标题】:How is this buffer really working?这个缓冲区是如何真正工作的?
【发布时间】:2014-12-26 23:03:51
【问题描述】:

作为 Linux 系统编程练习,我编写了自己的树命令版本,该命令仅使用基本的 read() 和 write() C 库函数从标准输入读取并写入标准输出。我这样做是为了在输入星号 (*) 时终止程序。我已经设法让它正常工作,我的问题是我不真的理解它为什么会这样工作。让我困惑的是缓冲区。首先,这里是有问题的代码部分:

char buf[1];
...
do {
    read(STDIN_FILENO, buf, 1);
    if( buf[0] == '*') break;
    write(STDOUT_FILENO, buf, 1);
} while( buf[0] != '*');
...

我的想法是逐个字符地从stdin char读取,从而将char存储在buf中,检查它是否是星号,然后将char从buf写入stdout。

行为如下:我键入一个任意数量的字符的字符串,按 ENTER,该字符串将输出到标准输出,此时我可以键入一个新的字符字符串。如果字符串以星号结尾,则字符串一直输出到星号为止,然后程序终止。

我的问题是:

1) buf 应该只包含一个字符。我怎么可能输入任意数量的字符,并且在按下 ENTER 后所有字符都输出到标准输出?我希望一次输出一个字符,或者只输出最后一个字符。单字符缓冲区如何存储所有这些字符?还是创建了许多单字符缓冲区?由谁?

2) 提示输出字符串的换行符有什么特别之处?为什么它不仅仅是字符串中的另一个字符?这只是函数 read() 中的定义问题吗?

感谢您在理解缓冲区工作方面提供的任何帮助!

【问题讨论】:

  • 操作系统负责缓冲程序中未缓冲的内容。换行符由终端驱动赋予意义;它指示终端驱动程序使先前输入的信息可用于 I/O 系统的其余部分。在输入换行符之前,终端驱动程序(O/S 的一部分)负责缓冲输入。它准备缓冲的内容有一个最大值,并且该最大值可能非常小(可能是 256 个字符;我没有检查 POSIX 指定的最小可接受最大值)。换行在文件中没有意义。

标签: c linux buffer


【解决方案1】:

这是基于 IO 调用的方式 - 读取和写入将在大多数操作系统上工作。

您只读取 1 个字节,因此在您输入时,内容将由 io 缓冲区(不是您的)保存,直到您的循环读取它。由于您没有睡眠,它会阅读,或者等待阅读的速度比您人工输入的速度要快。

也正如 R Sahu 所建议的 - 输入缓冲区可能不会出现在您的程序中,直到您在您正在输入的控制台上按 Enter 键。这取决于控制台及其配置 - 但大多数也会缓冲行并等待输入。如果您使用管道输入标准输入,情况会有所不同。

要读取的最后一个参数“1”指示它在此处读取一个字节。

第二部分是你的输出也被缓冲了,换行符通常被控制台输出缓冲区用来刷新和显示行。在这种情况下,您的代码会将其写入该输出缓冲区。如果您不想要这种行为,那么写入之后的 fflush 调用应该逐个字符地输出。

【讨论】:

  • 谢谢,我没想到我的程序中的缓冲区比缓冲区多!
【解决方案2】:

当您在控制台输入输入时,输入字符不会立即馈送到stdin。在您按下 Enter 按钮后,您键入的整行,包括换行符,都会被运行时环境提供给标准输入。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 2017-09-02
    • 2015-04-24
    相关资源
    最近更新 更多