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;
}