Search code examples
c++multithreadingboostoutput-buffering

Boost: how to create a thread so that you can control all of its standard output, standard errors?


I create a win32 console app in C++. I use some API (not mine, and I can not modify its sources). It Is written so that it writes some of its info onto console screen not asking... each time I call it (48 times per second) So I want to put it into some thread and limit its output capabilities, but I need to get notified when that thread will try to output some message which is important for me. I have message text in standard string. How to do such thing in C++ using boost?


Solution

  • That feature does not exist in Boost. You can, however, use _dup2 to replace the standard out descriptor:

    #include <cstddef>
    #include <cstdio>
    #include <cstdlib>
    #include <io.h>
    #include <iostream>
    #include <windows.h>
    
    int main()
    {
        HANDLE h = CreateFile(TEXT("test.txt"), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        if (0 == SetStdHandle(STD_OUTPUT_HANDLE, h)) {
            std::fprintf(stderr, "`SetStdHandle` failed with error %d\n", (int)GetLastError());
            return EXIT_FAILURE;
        }
    
        int h_desc = _open_osfhandle((long)h, 0);
        _dup2(h_desc, STDOUT_FILENO);
    
        std::printf("test\r\n"); // This actually writes to `h`.
        std::fflush(stdout);
    
        std::cout << "another test" << std::endl; // Also writes to `h`
    
        CloseHandle(h);
        return EXIT_SUCCESS;
    }
    

    Essentially what this trick does is allow you to redirect all writes to stdout, std::cout, and GetStdHandle(STD_OUTPUT_HANDLE) to a writable handle of your choosing (h). Of course, you can use CreatePipe to create the writable handle (h) and read from the readable end in another thread.

    EDIT: If you are looking for a cross-platform solution, note that this trick is even easier on POSIX-compatible systems because dup2 is a standard function in unistd.h and "writable handles" are already descriptors.