我正在使用文件描述符和posix / unix read()函数从C中的串行端口读取字节 . 在这个例子中,我从串口读取1个字节(为了清楚起见,省略了波特率设置和类似内容):
#include <termios.h>
#include <fcntl.h>
#include <unistd.h>
int main(void)
{
int fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY);
char buf[1];
int bytesRead = read(fd, buf, 1);
close(fd);
return 0;
}
如果连接到/ dev / ttyS0的设备未发送任何信息,程序将挂起 . 如何设置超时?
我试过像这样设置一个时间:
struct termios options;
tcgetattr(fd, &options);
options.c_cc[VMIN] = 0;
options.c_cc[VTIME] = 10;
tcsetattr(fd, TCSANOW, &options);
我认为它应该给1秒超时,但它没有任何区别 . 我想我误解了VMIN和VTIME . 什么是VMIN和VTIME用于?
然后我搜索了网络,发现有人在谈论select()函数 . 这是解决方案,如果是这样,如何将其应用于上述程序以使1秒超时?
任何帮助表示赞赏 . 提前致谢 :-)
5 回答
什么是VMIN和VTIME用于?
资料来源:http://tldp.org/HOWTO/Serial-Programming-HOWTO/x115.html
是的,请使用select(2) . 传入一个文件描述符集,其中只包含读取集中的fd和空写入/异常集,并传入适当的超时 . 例如:
您可以尝试捕获信号以停止读取操作 . 在读取之前使用alarm(1),如果没有返回读取功能,报警将发送SIGALRM信号,然后你可以创建信号处理功能来捕获这个信号,如下所示:
但如果您的程序很大,使用select或poll或epoll会更好 .
select()是解决这个问题的方法 .
互联网上有几个页面将提供有关如何使用select()的信息,例如http://www.unixguide.net/unix/programming/2.1.1.shtml
有几种可能的方法 . 如果程序最终将定时多个i / o操作,
select()
是明智的选择 .但是,如果唯一的输入来自此i / o,则选择非阻塞i / o和时序是一种简单的方法 . 我已经将它从单字符i / o扩展到多字符,使其成为一个更普遍的完整示例: