我正在尝试做一些我认为应该很简单的事情:从标准输入进行阻塞读取,但如果没有可用数据,则在指定的时间间隔后超时。
在 Unix 世界中这很简单select()
但这在 Windows 中不起作用,因为stdin
不是插座。不创建额外线程等的下一个最简单的选项是什么?
我正在使用针对 Win32 环境的 Visual C++。
到目前为止我已经尝试过:
using select
(如果输入不是套接字则不起作用)
using WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE))
。 - 雷米的第一个建议。如果标准输入是控制台,那么当您调用它时,这似乎总是立即返回(其他人报告了相同的问题)
使用重叠 IO 并执行WaitForSingleObject
(雷米的第三个建议)。在这种情况下,当输入来自控制台时,读取似乎总是被阻止 - 看起来stdin
不支持异步I/O。
目前,我认为我唯一剩下的选择是创建一个线程,该线程将执行阻塞读取,然后发出事件信号,然后让另一个线程等待超时事件。
我必须解决类似的问题。在 Windows 上,它不像 Linux 那样简单或明显。然而,这是可能的。诀窍在于 Windows 将控制台事件放入控制台输入事件队列中。您必须过滤掉您不关心的事件,并仅处理您确实关心的事件(例如按键)。
进一步阅读:请参阅 Win32 控制台文档 http://msdn.microsoft.com/en-us/library/windows/desktop/ms686971%28v=vs.85%29.aspx
以下是我正在研究的基于套接字和标准输入多路复用器的一些主要调试的示例代码:
void ProcessStdin(void)
{
INPUT_RECORD record;
DWORD numRead;
if(!ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &record, 1, &numRead)) {
// hmm handle this error somehow...
return;
}
if(record.EventType != KEY_EVENT) {
// don't care about other console events
return;
}
if(!record.Event.KeyEvent.bKeyDown) {
// really only care about keydown
return;
}
// if you're setup for ASCII, process this:
//record.Event.KeyEvent.uChar.AsciiChar
} // end ProcessStdin
int main(char argc, char* argv[])
{
HANDLE eventHandles[] = {
GetStdHandle(STD_INPUT_HANDLE)
// ... add more handles and/or sockets here
};
DWORD result = WSAWaitForMultipleEvents(sizeof(eventHandles)/sizeof(eventHandle[0]),
&eventHandles[0],
FALSE,
1000,
TRUE
);
switch(result) {
case WSA_WAIT_TIMEOUT: // no I/O going on right now
break;
case WSA_WAIT_EVENT_0 + 0: // stdin at array index 0
ProcessStdin();
break;
case WSA_WAIT_EVENT_0 + 1: // handle/socket at array index 1
break;
case WSA_WAIT_EVENT_0 + 2: // ... and so on
break;
default: // handle the other possible conditions
break;
} // end switch result
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)