3

我有一个 C++ 串行端口类,它具有无阻塞和阻塞模式用于读取操作。对于阻塞模式:

COMMTIMEOUTS cto;
GetCommTimeouts(m_hFile,&cto);
// Set the new timeouts
cto.ReadIntervalTimeout = 0;
cto.ReadTotalTimeoutConstant = 0;
cto.ReadTotalTimeoutMultiplier = 0;
SetCommTimeouts(m_hFile,&cto)

对于非阻塞模式:

COMMTIMEOUTS cto;
GetCommTimeouts(m_hFile,&cto);
// Set the new timeouts
cto.ReadIntervalTimeout = MAXDWORD;
cto.ReadTotalTimeoutConstant = 0;
cto.ReadTotalTimeoutMultiplier = 0;
SetCommTimeouts(m_hFile,&cto)

我想添加另一种模式来等待任意数量的字节并读取它们。

来自 MSDN COMMTIMEOUTS 结构

如果应用程序将ReadIntervalTimeoutReadTotalTimeoutMultiplier设置为MAXDWORD并将 ReadTotalTimeoutConstant 设置为大于零且小于 MAXDWORD 的值在调用 ReadFile 函数时会发生以下情况之一:

  • 如果输入缓冲区中有任何字节,ReadFile 会立即返回缓冲区中的字节。
  • 如果输入缓冲区中没有字节,ReadFile 会等到一个字节到达,然后立即返回。
  • 如果在 ReadTotalTimeoutConstant 指定的时间内没有字节到达,ReadFile 超时。

这看起来像这样的代码:

COMMTIMEOUTS cto;
GetCommTimeouts(m_hFile,&cto);
// Set the new timeouts
cto.ReadIntervalTimeout = 100;
cto.ReadTotalTimeoutConstant = MAXDWORD;
cto.ReadTotalTimeoutMultiplier = MAXDWORD;
SetCommTimeouts(m_hFile,&cto)

但这会在第一个字节上返回。这是一个问题,因为我正在循环读取端口,并且字节的处理速度非常快,以至于下次我读取端口时,只有另一个字节可用。最终结果是我在循环中一次读取一个字节,并使用 100% 的内核运行该线程。

我想使用cto.ReadIntervalTimeoutMSDN 文档中的类似内容,但仍要等到至少一个字节可用。有人有想法吗?

谢谢。

4

3 回答 3

5

您想要的行为将来自:

cto.ReadIntervalTimeout = 10;
cto.ReadTotalTimeoutConstant = 0;
cto.ReadTotalTimeoutMultiplier = 0;

对于第一个字节,它会阻塞任意长(根据文档,通过将后两个字段设置为零来禁用总超时),然后只要数据流入,就会读取到缓冲区大小。如果数据中有 10 毫秒的间隙,它将返回到目前为止已收到的内容。

于 2014-09-24T01:25:43.683 回答
1

如果您使用 100%(甚至接近)的 CPU,听起来您在其他地方做错了什么。正如我在之前的回答中所展示的那样,多年来我一直使用将超时设置为 1 的代码。我最初将它设置为这种方式只是对可能至少可以工作的东西的疯狂猜测,目的是调整它之后。它工作得很好,以至于我根本没有时间调整它。举例来说,它会使用几乎无法估量的 CPU 时间从我的 GPS 读取输入(这是我唯一拥有的甚至不再模仿使用串行端口的东西)——经过数小时从GPS,它仍然显示使用的 CPU 时间为 0:00:00 秒(无论它是否正在运行,我都看不出 CPU 使用率有任何差异)。

现在,我肯定会承认 GPS 不是(甚至接近于)最快的串行设备,但我们仍然在谈论 ~100% 与 ~0%。这显然是一个非常严重的区别。

于 2012-04-30T22:14:17.160 回答
0
if (dwEvtMask == EV_RXCHAR )
{
   Sleep(1);
   if (dwLength > 2)
    {
      Sleep(1);
      Readfile( m_Serial->m_hCom, data,dwLength, &dwBytesRead, &Overlapped);
      pDlg->PostMessage(WM_RECEIVE,0,0);
    }
}
于 2012-12-06T04:51:32.773 回答