c++写入stdin(在Windows中)
C++ write to stdin (in Windows)
我有一个多线程的Windows控制台应用程序,它的控制线程运行一个用户输入循环,像这样:
char c;
do {
cin >> c;
// Alter activity based on c
} while(c != 'q')
// Tell other threads to close, .join(), and do cleanup
然而,在某个时候,我希望程序本身能够优雅地退出。最明显的方法是将"qn"
放到标准输入流中。有什么合理的方法吗?
或者是一个很好的回调方法来强制退出主控制循环(在主线程上),以便程序进入后续的清理方法?
(到目前为止,我发现最接近的是这个,它需要生成一个子进程,看起来最好是笨拙的过度杀伤。)
您可以使用另一个标志作为所有线程的循环中断条件。线程间通信的问题可以通过c++ 11自带的同步对象(如原子或互斥锁)来解决。
我最终使用了@Captain Obvlious的建议,但即使这样也很棘手(感谢Windows!):一旦控制信号被处理,它就会导致各种未检查的char
输入循环问题。然而,通过以下添加,任何线程都可以通过调用GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0);
bool exiting = false;
bool cleanedUp = false;
void Cleanup() {
if(!cleanedUp) cleanedUp = true;
else return;
// Tell other threads to close, .join(), and do cleanup
}
// https://msdn.microsoft.com/en-us/library/ms683242(v=vs.85).aspx
bool ConsoleControl(DWORD dwCtrlType) {
exiting = true; // This will cause the stdin loop to break
Cleanup();
return false;
}
int main() {
SetConsoleCtrlHandler((PHANDLER_ROUTINE) ConsoleControl, true);
.
.
.
// Main user control loop
char c;
do {
cin >> c;
if(exiting) break;
if(c < 0) continue; // This must be a control character
// Alter activity based on c
} while(c != 'q')
Cleanup();
return 0;
}
这是一个老问题,但我偶然发现了它,最终解决了原来的问题。
我使用WriteConsoleInput函数来模拟用户向控制台输入按键。这个代码示例是基于这个问题的。
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
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 = 'q';
ir[0].Event.KeyEvent.wRepeatCount = 1;
ir[0].Event.KeyEvent.wVirtualKeyCode = 'Q';
ir[0].Event.KeyEvent.wVirtualScanCode = MapVirtualKey('Q', MAPVK_VK_TO_VSC);
ir[1].EventType = KEY_EVENT;
ir[1].Event.KeyEvent.bKeyDown = TRUE;
ir[1].Event.KeyEvent.dwControlKeyState = 0;
ir[1].Event.KeyEvent.uChar.UnicodeChar = VK_RETURN;
ir[1].Event.KeyEvent.wRepeatCount = 1;
ir[1].Event.KeyEvent.wVirtualKeyCode = VK_RETURN;
ir[1].Event.KeyEvent.wVirtualScanCode = MapVirtualKey(VK_RETURN, MAPVK_VK_TO_VSC);
WriteConsoleInput(hStdin, ir, 2, &dwTmp);
我的系统没有定义MAPVK_VK_TO_VSC
,所以我用0
代替。
你应该在适当的地方添加错误检查。
相关文章:
- 用于 Windows 写入临时文件的 mkstemp() 实现
- 以原子方式将彩色文本写入 Windows 中的控制台
- 在Windows上读取/写入未格式化的SD卡
- 在给定的处理器缓存的Windows中,页面写入跟踪的可靠性
- 使用 Windows API 写入和读取 Windows 注册表
- C++ Windows 管道写入文件到变量?
- 无法使用 ofstream 写入 Windows 7 中的临时文件夹
- 在C++中读取和写入Windows注册表(如何将字符串转换为wchar(?))
- 如何将x64机器代码写入虚拟内存并在C++中为Windows执行
- "printf"在 Windows 非控制台应用程序中写入何处?
- 如何使用 Windows API WriteFile 将 ASCII 字符串写入文件
- 在由另一个程序(Windows)写入文件时读取文件
- 用C 写入Windows安全日志
- Windows 7 的 QT 5.2 串行端口写入问题
- Windows是否允许同时写入文件
- 在写入远程Windows共享文件夹的所有者时,GetNamedSecurityInfo返回ERROR_ACCESS_DE
- 写入 Windows 下 Java 应用程序中生成的控制台应用程序C++
- 错误 6 句柄在 Windows 上写入文件无效
- 如何制作一个Windows程序,用于使用c ++将文件写入cd
- 使用 WinAPI/C++ 在 Windows 上的进程之间进行多读取器、单写入器同步锁定