5

我研究了许多有用的线程和一些教程,但我仍然遇到一些应该非常简单的问题。作为参考,这里有一些我仔细阅读过的线程:

如何在读取函数调用中实现超时?

如何在 C 中从串口打开、读取和写入

无论如何,我有一点问题。如果我收到数据,我的代码可以正常工作。如果我不这样做,read() 函数就会停止,退出程序的唯一方法是使用 kill -9 (注意:我使用信号处理向读取串行数据的线程发出信号以终止。这不是罪魁祸首,即使我删除了信号处理,read() 调用仍然会停止)。我想要做的是一次读取块并读取一个块(从而节省 CPU 使用率),但是如果读取没有收到数据,我不希望它超时。

以下是我应用于端口的设置:

struct termios serial_struct;
serial_struct.c_cflag = B115200 | CS8 | CLOCAL | CREAD;
serial_struct.c_iflag = IGNPAR;
serial_struct.c_oflag = 0;
serial_struct.c_lflag = 0;
serial_struct.c_cc[VTIME] = 1;  // timeout after .1s that isn't working
serial_struct.c_cc[VMIN] = 64;  // want to read a chunk of 64 bytes at a given time

然后我使用 tcsetattr() 设置这些设置,并确认端口通过 tcgetattr() 接收设置。我在想我的设置可能有冲突,因为我的读取似乎被阻塞并等到收到 64 个字节,但不要对超时做任何事情。我知道我可以使用 select() 来处理超时,但我希望避免多个系统调用。

与往常一样,提前感谢您的帮助。

4

1 回答 1

7

man 3 termios

最小值 > 0;TIME > 0:TIME 以十分之一秒为单位指定计时器的限制。一旦输入的初始字节可用,则在接收到每个其他字节后重新启动定时器。read(2) 在已读取请求的字节数或 MIN 字节中的较小者或字节间超时到期时返回。因为定时器仅在初始字节可用后启动,所以至少会读取一个字节。

请注意,在接收到至少一个字节的数据之前,定时器不会启动。在接收到第一个数据字节后,如果在接收连续数据字节之间存在 TIME 十分之一秒的间隙,则读取将超时。

于 2013-08-06T02:16:05.453 回答