首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用COMMTIMEOUTS等待字节可用,但读取多个字节?

如何使用COMMTIMEOUTS等待字节可用,但读取多个字节?
EN

Stack Overflow用户
提问于 2012-04-30 20:28:49
回答 3查看 26K关注 0票数 3

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

代码语言:javascript
复制
COMMTIMEOUTS cto;
GetCommTimeouts(m_hFile,&cto);
// Set the new timeouts
cto.ReadIntervalTimeout = 0;
cto.ReadTotalTimeoutConstant = 0;
cto.ReadTotalTimeoutMultiplier = 0;
SetCommTimeouts(m_hFile,&cto)

对于非阻塞模式:

代码语言:javascript
复制
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超时。

这在代码中如下所示:

代码语言:javascript
复制
COMMTIMEOUTS cto;
GetCommTimeouts(m_hFile,&cto);
// Set the new timeouts
cto.ReadIntervalTimeout = 100;
cto.ReadTotalTimeoutConstant = MAXDWORD;
cto.ReadTotalTimeoutMultiplier = MAXDWORD;
SetCommTimeouts(m_hFile,&cto)

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

我希望像在MSDN文档中一样使用cto.ReadIntervalTimeout,但仍然要等到至少有一个字节可用时才能使用。有谁有主意吗?

谢谢。

EN

回答 3

Stack Overflow用户

发布于 2014-09-24 01:25:43

您想要的行为将来自:

代码语言:javascript
复制
cto.ReadIntervalTimeout = 10;
cto.ReadTotalTimeoutConstant = 0;
cto.ReadTotalTimeoutMultiplier = 0;

它对第一个字节任意地阻塞很长时间(根据文档,将后两个字段设置为零来禁用总超时),然后读取到缓冲区大小,只要数据是流进来的。如果数据中有10‘s的缺口,它将返回到目前为止接收到的信息。

票数 6
EN

Stack Overflow用户

发布于 2012-04-30 22:14:17

如果您正在使用100% (甚至接近它)的CPU,听起来您在其他地方做错了什么。正如我在一个先前的回答中所展示的,多年来,我一直在使用将超时设置为1的代码。最初,我将其设置为一种疯狂的猜测,至少在某种程度上是可行的,目的是以后对其进行调优。它工作得很好,我根本就没有时间来调整它。例如,它将读取来自我的GPS的输入(这是我唯一能用串行端口模拟的东西),使用几乎无法测量的极小的CPU时间--经过几个小时从GPS读取一个恒定的数据流之后,它仍然显示了所用CPU时间的0:00:00秒(不管它运行与否,CPU的使用率都没有任何不同)。

现在,我可以肯定的是,GPS并不是(甚至接近)最快的串行设备,但我们仍然在谈论~100%和~0%。这显然是一个相当严重的区别。

票数 1
EN

Stack Overflow用户

发布于 2012-12-06 04:51:32

代码语言:javascript
复制
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);
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10390151

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档