I have an application, which reads data from standard input using getline() in a thread. I want to close the application from the main thread, while getline still block the other thread. How can this be achieved?
I don't want to force the users to have to press ctrl-Z to close stdin and the application.
I have tried so far with my complier settings (RuntimeLibrary=/MT) on Windows 8.1 64bit, v120 platform toolset:
* Update *
* Update 2: Solution *
Example code showing the problem:
#include <iostream>
#include <thread>
#include <string>
#include <chrono>
int main(int argc, char *argv[])
{
    bool stop = false;
    std::thread *t = new std::thread([&]{
        std::string line;
        while (!stop && std::getline(std::cin, line, '\n')) {
            std::cout << line;
        }
    });
    std::this_thread::sleep_for(std::chrono::seconds(1));
    stop = true;
    // how to stop thread or make getline to return here?
    return 0;
}
                writeConsoleInput() can make std::getline return from blocking read, so it can solve the problem even when /MT compiler option used.
#include <Windows.h>
#include <iostream>
#include <thread>
#include <string>
#include <chrono>
#include <atomic>
int main(int argc, char *argv[])
{
    std::atomic_bool stop;
    stop = false;
    std::thread t([&]{
        std::string line;
        while (!stop.load() && std::getline(std::cin, line, '\n')) {
            std::cout << line;
        }
    });
    std::this_thread::sleep_for(std::chrono::seconds(1));
    stop = true;
    DWORD dwTmp;
    INPUT_RECORD ir[2];
    ir[0].EventType = KEY_EVENT;
    ir[0].Event.KeyEvent.bKeyDown = TRUE;
    ir[0].Event.KeyEvent.dwControlKeyState = 0;
    ir[0].Event.KeyEvent.uChar.UnicodeChar = VK_RETURN;
    ir[0].Event.KeyEvent.wRepeatCount = 1;
    ir[0].Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
    ir[0].Event.KeyEvent.wVirtualScanCode = MapVirtualKey(VK_RETURN, MAPVK_VK_TO_VSC);
    ir[1] = ir[0];
    ir[1].Event.KeyEvent.bKeyDown = FALSE;
    WriteConsoleInput(GetStdHandle(STD_INPUT_HANDLE), ir, 2, &dwTmp);
    t.join();
    return 0;
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With