Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
336 views
in Technique[技术] by (71.8m points)

c - Do mixed writes to stdout and calls to WriteConsole always print to the console in the same order?

On Windows, I observe that if the output is redirected from the console to a file, then mixing calls to printf and Windows' WriteFile will result in the data being written to the file in a different order than the calls appeared in the code. Fair enough. That's understandable.

However, I've so far observed that when the output is directed to the console and I mix calls to printf and Windows' WriteConsole the data is always printed in the same order as the calls.

Is this latter behaviour guaranteed? Can I rely on it or are there situations where this order might change also?

Here's an example:

#include <stdio.h>
#include <windows.h>

int main() {
    DWORD lpMode;
    DWORD dwCount;
    HANDLE winout = GetStdHandle(STD_OUTPUT_HANDLE);
    BOOL is_console = GetConsoleMode(winout, &lpMode);
    if (is_console) {
        printf("Line 1 to console using printf.
");
        WriteConsoleA(winout, "Line 2 to console using WriteConsoleA.
", 39, &dwCount, NULL);
        printf("Line 3 to console using printf.
");
        WriteConsoleA(winout, "Line 4 to console using WriteConsoleA.
", 39, &dwCount, NULL);
        printf("Line 5 to console using printf.
");
        WriteConsoleA(winout, "Line 6 to console using WriteConsoleA.
", 39, &dwCount, NULL);
        printf("Line 7 to console using printf.
");
        WriteConsoleA(winout, "Line 8 to console using WriteConsoleA.
", 39, &dwCount, NULL);
    } else {
        printf("Line 1 to file using printf.
");
        WriteFile(winout, "Line 2 to file using WriteFile.
", 32, &dwCount, NULL);
        printf("Line 3 to file using printf.
");
        WriteFile(winout, "Line 4 to file using WriteFile.
", 32, &dwCount, NULL);
        printf("Line 5 to file using printf.
");
        WriteFile(winout, "Line 6 to file using WriteFile.
", 32, &dwCount, NULL);
        printf("Line 7 to file using printf.
");
        WriteFile(winout, "Line 8 to file using WriteFile.
", 32, &dwCount, NULL);
    }
    return 0;
}

When the output is redirected to a file, the file contains:

Line 2 to file using WriteFile.
Line 4 to file using WriteFile.
Line 6 to file using WriteFile.
Line 8 to file using WriteFile.
Line 1 to file using printf.
Line 3 to file using printf.
Line 5 to file using printf.
Line 7 to file using printf.

When the output is directed to the console, the following is printed:

Line 1 to console using printf.
Line 2 to console using WriteConsoleA.
Line 3 to console using printf.
Line 4 to console using WriteConsoleA.
Line 5 to console using printf.
Line 6 to console using WriteConsoleA.
Line 7 to console using printf.
Line 8 to console using WriteConsoleA.

To be clear, I'm not asking about WriteFile here. My question is not about why the first set of output to the file is in the “incorrect” order, but rather why the second set of output to the console is in the “correct” order, and when (if ever) this behaviour cannot be assumed for WriteConsole.

question from:https://stackoverflow.com/questions/65870896/do-mixed-writes-to-stdout-and-calls-to-writeconsole-always-print-to-the-console

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You are never going to get guaranteed behavior here because mixing raw Win32 API and the C API is probably not a supported scenario.

Calling fflush after printf is probably going to fix it for you but the best option is to not mix different APIs. To be really sure you might want to call FlushFileBuffers after WriteFile as well but that might degrade performance too much if you write a lot of data.

If you can't add fflush calls, another alternative you can try is _open_osfhandle + dup2 to replace stdout and then call setbuf/setvbuf to disable buffering.

The console does not use files, older versions of Windows use a synchronous API to communicate with another process (csrss or conhost) and newer versions use IOCTLs. WriteFile has a special hook that uses this other API if the file handle is the console.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...