windows 可以在 ReadFile() 上超时吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4063051/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 15:30:49  来源:igfitidea点击:

possible to have a Timeout on ReadFile()?

c++windows

提问by aCuria

while(GetExitCodeProcess(processInfo.hProcess, &exitCode)
        && exitCode == STILL_ACTIVE)
{
    ReadFile(defaultSTDIN, chBuf, 1, &dwRead, 0);
    WriteFile(writingEnd, chBuf, 1, &dwWritten, 0);
}

The problem with the code above is that even when the child process referenced through processInfo.hProcess has exited, we are still stuck in the while loop because ReadFile() is waiting for input. Whats the best way to solve this?

上面代码的问题在于,即使通过 processInfo.hProcess 引用的子进程已经退出,我们仍然停留在 while 循环中,因为 ReadFile() 正在等待输入。解决这个问题的最佳方法是什么?

回答by yonilevy

What you need is to read the file asynchronously using the FILE_FLAG_OVERLAPPEDflag when opening the file, and specifying an OVERLAPPEDstructure to the ReadFilefunction. Then you could wait on both the read operation and the process termination, and act appropriately.

您需要的是FILE_FLAG_OVERLAPPED在打开文件时使用标志异步读取文件,并OVERLAPPEDReadFile函数指定结构。然后您可以等待读取操作和进程终止,并采取适当的行动。

回答by C.D.H.

It is possible to assume a timeout with a non-overlapped ReadFile, but indirectly.

可以假设一个非重叠的 ReadFile 超时,但是是间接的。

First you must set the timeouts for the handle using SetCommTimeoutsspecifically there has to at least be a value set to the ReadTotalTimeoutConstantpassed to this function. (One caveat: This works when your handle points to a comm port, not sure how it might work if that is actually a file being read.)

首先,您必须使用SetCommTimeouts为句柄设置超时,特别是必须至少有一个值设置为传递给此函数的ReadTotalTimeoutConstant。(一个警告:当您的句柄指向一个通信端口时,这会起作用,如果这实际上是一个正在读取的文件,则不确定它会如何工作。)

With that set up appropriately the ReadFilefunction will kick out either when its done filling its buffer, reaches end of file, or when it reaches the timeout. its not going to throw any errors or anything so to determine that a timeout occured you need to compare your &dwReadto the number of expected bytes. since you are only looking for 1 byte, if dwRead = 0then you had a timeout, and not an end of file.

适当设置后,该ReadFile函数将在完成填充缓冲区、到达文件末尾或达到超时时退出。它不会抛出任何错误或任何东西,以便确定发生了超时,您需要将&dwRead与预期的字节数进行比较。因为您只查找 1 个字节,if dwRead = 0所以您有一个超时,而不是文件结尾。

So the way I'd write it (and I can't claim that I'm following best practices or anything) is to do the following:

所以我写它的方式(我不能声称我正在遵循最佳实践或任何东西)是执行以下操作:

    COMMTIMEOUTS timeouts = { 0, //interval timeout. 0 = not used
                              0, // read multiplier
                             10, // read constant (milliseconds)
                              0, // Write multiplier
                              0  // Write Constant
                            };


    SetCommTimeouts(defaultSTDIN, &timeouts);

    while(GetExitCodeProcess(processInfo.hProcess, &exitCode)
          && exitCode == STILL_ACTIVE)
    {
        ReadFile(defaultSTDIN, chBuf, 1, &dwRead, 0);
        if (dwRead == 0) {
                     //insert code to handle timeout here
        }
        WriteFile(writingEnd, chBuf, 1, &dwWritten, 0);
    }