WaitForMultipleObjectsEx如何在ReadTotalTimeoutConstant之前超时?

时间:2015-09-15 15:59:13

标签: windows serial-port overlapped-io

我有一个从串口读取的程序,这是通过重叠IO完成的。当我在SetCommTimeouts(100 ms)调用中具有较低的超时时,我无法理解WaitForMultipleObjects如何超时(200 ms)。它很少发生。但是当它发生时,它经常发生在多个不同的串行端口上。有时它也在不同的应用程序中使用相同的源代码在不同的COM端口上进行通信。

程序将首先使用:

打开com端口
 CreateFile(szCommDevice, GENERIC_READ | GENERIC_WRITE, 0, NULL,
             OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); 

打开后,它将调用GetCommProperties和PurgeComm,然后:

timeouts.ReadIntervalTimeout = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 100;
SetCommTimeouts(hComHandle, &timeouts);

在开始在循环中读取端口之前,它还调用SetCommState和SetCommMask:

dwRequestedSize = dwClearError();
if( dwRequestedSize <= 0 )
    dwRequestedSize = 1;
else if( dwRequestedSize > nBufferSize )
    dwRequestedSize = nBufferSize;

if (!ReadFile(hComHandle, clReceived.pBuffer, dwRequestedSize , &dwRead, &osReader ))
{
    DWORD dwLastError = GetLastError();
    if ( dwLastError != ERROR_IO_PENDING)
    {
        bCloseComPort();
        continue;
    }
    else
        fWaitingOnRead = TRUE;
}
else // read completed immediately
{
    if( dwRead > 0 )
    {
        // Add To Receive Buffer
    }
}

使用cbInQue从ClearCommError启动dwRequestedSize。所以这是缓冲区中的字节数。在开始等待:

之前,代码还将调用具有重叠IO的WaitCommEvent
DWORD dwRes = WaitForMultipleObjectsEx(2 , hEventArray, FALSE,  200 , true );
switch(dwRes)
{
    // Read completed.
    case WAIT_OBJECT_0:
        if (!GetOverlappedResult(hComHandle, &osReader, &dwRead, FALSE))
        {
           bCloseComPort();
        }   // Error in communications; report it.
        else // Read completed successfully.
        {
            if( dwRead > 0 )
            {
                // Add To Receive Buffer
            }
        }
        //  Reset flag so that another opertion can be issued.
        fWaitingOnRead = FALSE;
        break;

    // Status completed
    case WAIT_OBJECT_0 + 1:
        if (!GetOverlappedResult(hComHandle, &osStatus, &dwOvRes, FALSE))
        {
           bCloseComPort();
        }   // Error in communications; report it.
        else
        {
            ReportStatusEvent(dwCommEvent);
        }
        fWaitingOnStat = FALSE;
        break;

    case WAIT_TIMEOUT:
        // Why can I get here ?
        break;
}

我在这里做错了吗? 感谢您的任何意见。

一些其他信息。

我知道分页可能是一个问题。但出于两个原因,我仍然不愿意接受这一点。

1)计算机只运行所描述的软件,没有用户与PC的交互,并且它有足够的RAM(4千兆字节),应用程序只使用大约50 MB的内存。因此,Pc始终具有至少2千兆字节的可用内存。

2)应用程序全天候运行,并且围绕此代码的活动非常繁重,它将发送数据或接收数据。所以我假设Windows不会选择代码或内存作为寻呼的候选者。

也许有一些我不完全理解的分页,在这种情况下你能解释一下吗。

我想我会添加一张支票来查看实际等待时间。我假设等待大约200毫秒。然后可以排除分页或其他窗口锁定的东西。因为它不太可能,它将完全相同的200毫秒。同意?我假设GetTickCount对此具有很高的精度,这将增加最少的开销。

0 个答案:

没有答案