Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Sleep()是一个糟糕的设计,但似乎是我唯一的选择_C++_Windows_Serial Port_Sleep - Fatal编程技术网

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

C++ Sleep()是一个糟糕的设计,但似乎是我唯一的选择,c++,windows,serial-port,sleep,C++,Windows,Serial Port,Sleep,我正在编写一个IO类,通过RS-232串行总线将文件上传/下载到控制器。不幸的是,我不能一次发送一个完整的文件,我必须把它分成包,一次发送一点。以下是基本方法 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(

我正在编写一个IO类,通过RS-232串行总线将文件上传/下载到控制器。不幸的是,我不能一次发送一个完整的文件,我必须把它分成包,一次发送一点。以下是基本方法

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()语句,甚至缩短循环休眠的时间,那么控制器就会抛出错误,说明它的缓冲区已满,并且传输失败有更好的方法吗?

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

编辑: 我忘了提到我必须睡觉的时间间隔有点“盲目”。制造商提供的协议规范没有详细说明数据包之间所需的任何时间长度。所以我必须通过反复试验来确定这个值。我担心它可能无法在每台电脑上工作,甚至无法在每台控制器上工作

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

编辑#2:
此外,每个数据包的数据量实际上也是一个试错猜测。协议规范允许65535字节的数据包(包括报头)。但如果一次发送的字节数超过129个,就会出现问题,有时有效,有时无效。在你必须睡眠的时间和你可以发送的字节数之间似乎也有关系。如果我将数据包大小降低到每个数据包20字节,我可以将睡眠时间降低到400毫秒。我认为,这些问题的原因在于控制器将数据从缓冲区移动到文件所需的时间

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

设备通常指定最大数据速率或字节之间的最小时间


我认为这是一种不好的做法,其原因是盲目地选择延迟值(如果延迟值大于需要的值,则性能会受到影响)、有更好的同步方法可用,或者使用延迟来掩盖计时问题(例如,在多线程应用程序中).

睡眠可能不是正确的另一个原因是您可能希望尽早退出该功能。如果你真的这么做了

WaitForSingleObject(hTerminatingEvent, 600);

您可以让另一个线程通知您要退出并提前终止的事件。(在这种情况下,即使事件未发出信号,此函数调用也将在600毫秒后继续。)

在Windows上,我会使用可等待的计时器,而不是
Sleep()
,但如果硬件需要延迟,然后你需要延迟。

你总是从控制器那里得到答案吗?如果你的硬件要求包括一次发送这么多字节,然后等待这么多毫秒,那么显然没有更好的方法来实现它。是的,我甚至敢说,使用睡眠并不是一个坏主意。我想您可以编写一个奇特的函数,包括但给定您的条件,Sleep()听起来很合理。从什么时候开始,Sleep是一个糟糕的设计实践@尼尔斯潘布林克:我认为这没有关系。它只是将完全相同的功能委托给一个库线程。