java 非阻塞读取_termios VMIN VTIME和阻塞/非阻塞读取操作
安德烈是对的 . 在非阻塞模式下,VMIN / VTIME无效(FNDELAY / O_NDELAY似乎是O_NONBLOCK的linux变体,便携式,POSIX标志) .
将select()与非阻塞模式的文件一起使用时,会为每个到达的字节获取一个事件 . 在高串行数据速率下,这会破坏CPU . 最好在VMIN中使用阻塞模式,以便select()在触发事件之前等待数据块,而VTIME用于限制小于VMIN的块的延迟 .
Sam说:“如果你想确保每半秒获得一次数据就可以设置vtime”(VTIME = 5) .
直觉上,你可能会认为这是真的,但事实并非如此 . BSD termios手册页比linux更好地解释了它(尽管它们的工作方式相同) . VTIME定时器是一个间歇定时器 . 它从每个新字节到达串行端口开始 . 在最坏的情况下,select()可以在触发事件之前等待最多20秒 .
假设您有VMIN = 250,VTIME = 1和串行端口为115200 bps . 还假设您有一个连接设备缓慢发送单个字节,以9 cps的一致速率 . 字节之间的时间为0.11秒,足以使0.10的字节间定时器到期,而select()则报告每个字节的可读事件 . 一切都很好 .
现在假设您的设备将其输出速率提高到11 cps . 字节之间的时间是0.09秒 . 它不足以让间歇计时器到期,并且每个新字节都会重新开始 . 要获得可读事件,必须满足VMIN = 250 . 在11 cps,这需要22.7秒 . 您的设备似乎已停滞不前,但VTIME设计是导致延迟的真正原因 .
我使用两个Perl脚本,发送器和接收器,双端口串行卡和零调制解调器电缆对此进行了测试 . 我证明了它的工作原理正如man page所说的那样 . VTIME是一个间歇定时器,随着每个新字节的到来而复位 .
更好的设计会使计时器锚定,而不是滚动 . 它将继续滴答,直到它到期,或VMIN满意,以先到者为准 . 现有设计可以修复,但需要克服30年的遗产 .
在实践中,您可能很少遇到这种情况 . 但它潜伏着,所以要小心 .
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
