在 C 中获取 Windows 串行端口的输入缓冲区长度
Getting input buffer length for Windows serial port in C
是否有非阻塞函数returns Windows 中串行端口的当前 rx 队列长度,使用 C?
我见过的所有示例都简单地调用了 ReadFile
,它会阻塞到指定的超时时间,所以我想知道是否可以在读取之前检查缓冲区中是否有任何内容?
例如我可以简单地为每个角色执行此操作:
void ReadCharacter(char *theCharacter)
{
DWORD numBytesRead = 0;
while (numBytesRead == 0)
{
ReadFile(comPorthandle,
theCharacter,
sizeof(char),
&numBytesRead,
NULL);
}
}
但是有没有可能像
int numBytesRx = GetNumBytesRx(&portHandle);
if (numBytesRx > 0)
Read(&portHandle, targetBuffer, numBytesRead);
要通过 ReadFile
使用 COM 端口执行异步 IO,请考虑使用函数的最后一个参数,LPOVERLAPPED
和 OVERLAPPED
结构。 OVERLAPPED
是 Windows 中异步 IO 的常见做法。
ReadFile
将始终 return rx 缓冲区中已有的任何内容。因此,如果您不设置超时,您将立即获得内容。
不过请注意,没有专业应用程序会将 ReadFile
置于忙等待循环中。这不仅会不必要地耗尽 CPU,还会阻塞存在循环的线程。
所以你应该把 ReadFile
放在它自己的线程中。这是所有 I/O 函数的常见做法。这将解决阻塞问题,但您仍然会遇到 CPU 使用率高的问题。
作为替代方案,您可以使用 Windows 调用 "asynchronous I/O" (*) 的方法,方法是使用 ReadFileEx
函数。它允许您指定一个回调函数,只要您实际收到一些数据就会触发该函数。
现在,如果您将 "asynchronous I/O" 与线程结合使用,您将获得一种非阻塞通信,当没有要处理的数据时,它不会消耗 CPU。您的 I/O 线程可以使用 SleepEx
等待 I/O,也可以等待您从回调内部手动设置的事件。
(*) "Asynchronous I/O" 是无意义的 Windows 术语,因为从技术上讲,所有串行端口通信始终是异步的。如果您不间断地同步发送数据,速度较慢的台式 PC 将无法跟上。
是否有非阻塞函数returns Windows 中串行端口的当前 rx 队列长度,使用 C?
我见过的所有示例都简单地调用了 ReadFile
,它会阻塞到指定的超时时间,所以我想知道是否可以在读取之前检查缓冲区中是否有任何内容?
例如我可以简单地为每个角色执行此操作:
void ReadCharacter(char *theCharacter)
{
DWORD numBytesRead = 0;
while (numBytesRead == 0)
{
ReadFile(comPorthandle,
theCharacter,
sizeof(char),
&numBytesRead,
NULL);
}
}
但是有没有可能像
int numBytesRx = GetNumBytesRx(&portHandle);
if (numBytesRx > 0)
Read(&portHandle, targetBuffer, numBytesRead);
要通过 ReadFile
使用 COM 端口执行异步 IO,请考虑使用函数的最后一个参数,LPOVERLAPPED
和 OVERLAPPED
结构。 OVERLAPPED
是 Windows 中异步 IO 的常见做法。
ReadFile
将始终 return rx 缓冲区中已有的任何内容。因此,如果您不设置超时,您将立即获得内容。
不过请注意,没有专业应用程序会将 ReadFile
置于忙等待循环中。这不仅会不必要地耗尽 CPU,还会阻塞存在循环的线程。
所以你应该把 ReadFile
放在它自己的线程中。这是所有 I/O 函数的常见做法。这将解决阻塞问题,但您仍然会遇到 CPU 使用率高的问题。
作为替代方案,您可以使用 Windows 调用 "asynchronous I/O" (*) 的方法,方法是使用 ReadFileEx
函数。它允许您指定一个回调函数,只要您实际收到一些数据就会触发该函数。
现在,如果您将 "asynchronous I/O" 与线程结合使用,您将获得一种非阻塞通信,当没有要处理的数据时,它不会消耗 CPU。您的 I/O 线程可以使用 SleepEx
等待 I/O,也可以等待您从回调内部手动设置的事件。
(*) "Asynchronous I/O" 是无意义的 Windows 术语,因为从技术上讲,所有串行端口通信始终是异步的。如果您不间断地同步发送数据,速度较慢的台式 PC 将无法跟上。