【问题标题】:Standard output hangs after adding fprintf() statement with custom standard error添加带有自定义标准错误的 fprintf() 语句后标准输出挂起
【发布时间】:2012-01-19 13:47:29
【问题描述】:

我有一个 C++ 类 Archive 和一个成员函数 extractData()。此函数调用realExtractData(),它在单独的 C 库中实现。

我想向extractData() 函数传递一对FILE * 实例,通常是stdoutstderr,但我也想提供自定义文件指针的选项:

class Archive {
    public:
        ...
        int extractData(string id, FILE *customOut, FILE *customErr);
        ...
};

int
Archive::extractData(string id, FILE *customOut, FILE *customErr)
{
    if (realExtractData(id.c_str(), customOut) != EXIT_SUCCESS) {
        fprintf(stderr, "something went wrong...\n");
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

如果我按所列方式调用上述内容,则将数据输出到标准输出没有延迟。所有提取的数据几乎立即发送到标准输出 (stdout):

FILE *outFp = stdout;
FILE *errFp = stderr;
Archive *archive = new Archive(inFilename);

if (archive->extractData(id, outFp, errFp) != EXIT_SUCCESS) {
    fprintf(errFp, "[error] - could not extract %s\n", archive->getInFnCStr());
    return EXIT_FAILURE;
}

如果我更改extractData() 使其fprintf() 调用使用customErr

int
Archive::extractData(string id, FILE *customOut, FILE *customErr)
{
    if (realExtractData(id.c_str(), customOut) != EXIT_SUCCESS) {
        fprintf(customErr, "something went wrong...\n");  /* <-- changed this line */
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

...然后当我运行二进制文件时,二进制文件似乎在处理输入和打印到标准输出时挂起。

如果我将fprintf() 改回使用stderr 而不是customErr,那么一切都会再次正常运行,,数据会立即刷新到标准输出(我的customOut)。

这是一个缓冲问题吗?有没有办法解决这个问题?

【问题讨论】:

    标签: c++ c stdout stderr buffering


    【解决方案1】:

    “stderr 而不是 customErr”

    标准错误是无缓冲的,这意味着它几乎会立即打印出来。除非您使用低级操作系统调用,否则其他输出流将被缓冲,这意味着它们将需要更长的时间才能打印,除非您使用 endl、::flush 或其他任何东西进行缓冲区刷新。

    如果您想进行低级操作系统调用并且正在使用 unix,请查看:

    http://www.annrich.com/cs590/notes/cs590_lecture_2.pdf

    我还没有通读整本书,但是在扫描它时,它似乎与优秀的 Stevens Advanced Programming in Unix 这本书有类似的信息,这本书肯定会谈到这一点。

    【讨论】:

    • 我应该在哪里拨打fflush() 电话?如果我将它放在fprintf() 语句之后,它似乎无法解决挂起问题。
    • 老实说,我会尝试摆脱 fprintf 以支持直接进行无缓冲 write() 调用,如该链接中所述。这是我认为它与 std::cerr/stderr 打印输出一样快的唯一方法。
    猜你喜欢
    • 2014-03-22
    • 1970-01-01
    • 2017-10-02
    • 2019-11-08
    • 2017-07-21
    • 1970-01-01
    • 1970-01-01
    • 2013-05-11
    • 2014-07-22
    相关资源
    最近更新 更多