Win32 - 从标准输入读取超时

新手上路,请多包涵

我正在尝试做一些我认为应该很简单的事情:从标准输入进行阻塞读取,但是如果没有可用数据,则在指定的时间间隔后超时。

在 Unix 世界中,使用 select() 这很简单,但在 Windows 中不起作用,因为 stdin 不是套接字。在不创建额外线程等的情况下,下一个最简单的选项是什么?

我正在使用针对 Win32 环境的 Visual C++。

到目前为止,我已经尝试过:

  1. 使用 select (如果输入不是套接字则不起作用)

  2. 使用 WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE)) 。 - 雷米的第一个建议。如果标准输入是控制台,当您调用它时,这似乎总是立即返回(其他人报告了同样的问题)

  3. 使用重叠 IO 并执行 WaitForSingleObject (雷米的第三个建议)。在这种情况下,当输入来自控制台时,读取似乎总是阻塞 - 似乎 stdin 不支持异步 I/O。

目前我在想我唯一剩下的选择是创建一个线程来执行阻塞读取,然后发出一个事件信号,然后让另一个线程超时等待事件。

原文由 Andy 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 704
1 个回答

我不得不解决一个类似的问题。在 Windows 上,它不像 Linux 那样简单或明显。然而,这是可能的。诀窍是 Windows 将控制台事件放在控制台输入事件队列中。你必须过滤掉你不关心的事件,只处理那些你关心的事件(比如按键)。

如需进一步阅读: 请参阅 Win32 控制台文档

这是一些基于我正在研究的套接字和标准输入多路复用器的大部分调试示例代码:

 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
}

原文由 Clay 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题