在Windows中,如何使用非阻塞stdin作为重定向管道?

pal*_*ogt 7 c c++ windows stdin pipe

我有一个Windows C程序通过重定向stdin管道获取其数据,有点像这样:

./some-data-generator | ./myprogram
Run Code Online (Sandbox Code Playgroud)

问题是我需要能够以stdin非阻塞方式读取.原因是(1)输入是数据流,没有EOF,(2)程序需要能够stdin在任何时候中止其读取线程. fread当没有数据时阻塞,所以这使得它非常困难.

在Unix上,这是没有问题的,因为你可以设置一个文件描述符的阻塞模式fcntlO_NONBLOCK.但是,fcntlWindows上不存在.

我试过用SetNamedPipeHandleState:

    DWORD mode= PIPE_READMODE_BYTE|PIPE_NOWAIT;
    BOOL ok= SetNamedPipeHandleState(GetStdHandle(STD_INPUT_HANDLE), &mode, NULL, NULL);
    DWORD err= GetLastError();
Run Code Online (Sandbox Code Playgroud)

但这与ERROR_ACCESS_DENIED(0x5)失败了.

我不知道还能做什么.这实际上是不可能的(!)还是只是高度混淆了?对于这个特定问题,网络上的资源相当稀少.

kcw*_*cwu 6

订单方法,检查是否有可供读取的输入:

  • 对于控制台模式,您可以使用 GetNumberOfConsoleInputEvents()。
  • 对于管道重定向,您可以使用 PeekNamedPipe()