我正在从一个设备上读取数据,这个设备以某种可能变化的速率提供无休止的字节流。(对于好奇的人来说,这是一个真正的USB接口)。它不会在读取时返回EOF。因为我想要在特定的时间段内有一定数量的字节,所以每次我想要字节时,我都会做一个循环,使用一个带有超时和POLLIN的ppoll,如果这不表示超时,则读取。我把读取给我的字节累加起来,如果没有得到足够的字节,我重新计算时间延迟,然后(如果还有时间)返回到ppoll。非常简单。
除了偶尔一次,ppoll返回时会显示有数据(即revents是POLLIN)。。。read返回0。
同样,这不是那种应该返回0到信号流结束的设备,因为它没有结束。如果我忽略0,只需再次遍历,我将继续获取字节。注意,我从未见过在第一次读取循环时发生这种情况;通常它会读取几次,每次读取几个字节,然后砰的一声。
为了使它更有趣,如果我在ppoll和read之间添加一个sched_yield,read将停止返回0(或者可能更少见)。这很奇怪,因为这是一个4个处理器的系统,我怀疑即使是3个处理器也不能同时忙;sched_yield应该总是立即返回。
教代码把0当作oops并继续下去并不困难。但我宁愿不这样做;我希望在这种情况下永远不会看到0,我想把它当作错误的证据。毕竟,如果它一遍又一遍地发生,线就会旋转。(在这个案例中加入usleep(500)是一个黑客解决方案。)
所以问题是,这是内核种族状况的证据吗?或者设备的驱动程序(它是一个标准的USB“串行”设备)会导致这种情况吗?基本上我想知道该向谁投诉,或者我是否有权投诉。在ppoll说要读取数据后,我绝不会期望read从产生数据的设备返回0。
注意,我使用这个ppoll read函数来读取/dev/random,它永远不会返回0。是关于这个USB设备的。我已经在它周围编码,所以我只是在寻找理解,而不是修复。欢迎启蒙运动。
最佳答案
谜底的答案是:我是个白痴。
我没有将文件句柄设置为原始模式。随机生成的字符被解释为行编辑、EOF和其他各种胡言乱语。读取计数相应地是愚蠢的;特别是EOF可以导致返回0字节。
关于linux - ppoll的神秘案例,读0长度(Linux,raspberry pi),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51581369/