c++ - Sleep() 是一个糟糕的设计,但似乎是我唯一的选择

标签 c++ windows serial-port sleep

我正在编写一个 IO 类,通过 RS-232 串行将文件上传/下载到 Controller 。不幸的是,我不能一次发送整个文件,我必须将它分成数据包并一次发送一点点。这是基本方法...

ifstream file ("path/to/file.ext", ios::in | ios::binary);

while( !file.eof() )
{
    //... zero buffer, and add packet header (8 bytes)
    size_t nResult = file.read( &buffer[8], 129 );
    Serial.Write( buffer, nResult+8 );
    //... see if controller wrote anything to the serial port and process it's command
    Sleep( 600 );
}

我知道使用 Sleep() 不是一个好的设计实践,但如果我删除 Sleep() 语句或什至缩短循环休眠的时间量,那么 Controller 会抛出有关其缓冲区已满的错误,并且传输失败。 有更好的方法吗?

在你说之前,不,我不能向 Controller 发送消息以确定它是否已准备好接收下一个数据包。它没有那个功能。

编辑: 我忘了提到我必须 sleep 的时间间隔有点“盲目”。制造商提供的协议(protocol)规范没有详细说明数据包之间所需的任何时间长度。所以我必须通过反复试验来确定该值。恐怕它可能无法在每台 PC 上运行,而且可能无法在所有 Controller 上运行。

此开发是针对 Windows XP/Vista/7 进行的。

编辑#2: 此外,每个数据包的数据量实际上也是一个反复试验的猜测。协议(protocol)规范允许 65,535 字节的数据包(包括 header )。但是,如果您一次发送超过 129 个字节,您就会开始发现有时有效有时无效的问题。你必须 sleep 的时间和你可以发送的字节数之间似乎也有关系。如果我将数据包大小降低到每个数据包 20 个字节,我就可以将 sleep 时间降低到 400 毫秒。我相信这些问题的原因源于 Controller 将数据从其缓冲区移动到文件所花费的时间。

最佳答案

您所做的称为盲循环同步。这不一定是糟糕的设计。如果您的设备没有指示它是否已准备好接收更多数据的功能,这是唯一的方法。

设备通常会指定最大数据速率或字节之间的最短时间量。

我认为这是不好的做法的想法来自以下情况:您盲目地选择延迟值(如果它大于需要的值,性能会受到影响),如果您有更好的同步方法可用,或者如果您正在使用延迟以掩盖计时问题(例如,在多线程应用程序中)。

关于c++ - Sleep() 是一个糟糕的设计,但似乎是我唯一的选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8249340/

相关文章:

windows - Windows 服务的 DirectX 访问

c++ - 如何获取特定用户的 Windows "special folder"路径?

c - 向指定端口写入/读取命令

java - 在写入该值之前检查变量是否包含特定值是否是明智的优化?

c++ - 按键事件及其重载

c++ - 在C++中将对象添加到2D vector

c# - .net 应用程序在通过计划任务触发时失败

c++ - boost::算法::包含

如果不使用 minicom 打开一次,则无法从串口读取

c# - WaitFor() - 如何等待特定缓冲区到达 Steam/SerialPort?