【问题标题】:About the read() in unistd.h (C++)关于 unistd.h (C++) 中的 read()
【发布时间】:2011-12-18 06:03:14
【问题描述】:

大家好,我在设计一个Key-Value服务器,在写客户端的时候,发现一个很奇怪的东西,看简化代码:

while(1)
{
    printf("->:");
    read(STDIN_FILENO, buf, sizeof(buf));
    write(client_sock, buf, sizeof(buf));
    int m = read(client_sock, buf, sizeof(buf));
    buf[m] = '\0';
    printf("%s", buf);
}

当我运行程序时,它首先要求输入,所以我输入了一些东西,但没有任何反应! (当我使用其他客户端时,服务器运行良好,并且它很好地回显了一些东西)

那我只改了一行代码:

printf("\n->:");

然后它运行良好!为什么?为什么“\n”可以改变输出?我想可能是 read() ,但我无法解释

【问题讨论】:

    标签: c++ unistd.h


    【解决方案1】:

    printf(3) 是 C 标准 IO 库的一部分,它执行内部缓冲以提高性能。

    有三种类型的缓冲:无、行和块。

    应用哪个缓冲部分取决于要写入的描述符是否为2,以及它是否连接到终端。 (见isatty(3)。)

    如果打印到 stderr (2) 则不进行缓冲。

    如果对任何其他描述符进行打印,则无论它是否为终端,行为都会发生变化:如果输出是终端,则输出是行缓冲。如果输出不是终端(文件、管道、套接字等),那么输出是块缓冲

    当行缓冲时,它会在打印任何内容之前等待\n。 (或者,如果您在发送 \n 之前写入的内容足以溢出内部缓冲区。)

    我推荐的是以下内容:

    printf("->:");
    fflush(stdout);
    read(STDIN_FILENO, buf, sizeof(buf));
    /* ... */
    printf("%s\n", buf);
    

    这是一个小变化;你不会在程序启动时得到一个毫无意义的空行,并且提示应该立即显示出来。

    您可以使用setvbuf(3) 函数在启动时更改一次流的缓冲,如果您愿意,则无​​需再次刷新它。

    int err = setvbuf(stdout, NULL, _IONBF, 0);
    /* check err */
    

    【讨论】:

      【解决方案2】:

      标准输出默认是行缓冲的。如果您不写完整的行,则输出将保存在缓冲区中,直到您写完为止。您可以使用fflush 刷新流或使用setbuf 更改缓冲模式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-11-11
        • 1970-01-01
        • 1970-01-01
        • 2013-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多