ppoll的神秘案例,读取长度为0(Linux,raspberry pi)

时间:2018-07-29 14:35:54

标签: linux polling

我正在从一台设备读取内容,该设备以某种可能变化的速率提供无休止的字节流。 (出于好奇,它是USB TrueRNG)。它不是在读取时返回EOF的东西。因为我希望在特定的时间范围内有一定数量的字节,所以每次我想要字节时,我都会使用一个带有超时和POLLIN的ppoll进行循环,如果这不表示超时,则进行一次读取。我积累了读取的所有字节数,如果还不够的话,我将重新计算时间延迟,然后(如果还有剩余时间)返回到ppoll。很简单。

除偶尔出现一次,ppoll会返回并指示有数据(即,revents是POLLIN)...并且读取返回0。

同样,这不是应该返回0来指示流结束的设备,因为它没有末尾。如果我忽略了0,然后又走了一次,我将继续获得字节。注意,我从未见过在第一次读取循环时发生这种情况。通常它会读取几次,每次都抓取几个字节,然后爆炸。

为了使它更有趣,如果我在ppoll和read之间添加了sched_yield,则read停止返回0(或者可能更罕见)。这很奇怪,因为这是一个4处理器系统,我怀疑甚至3个处理器一次都忙。 sched_yield应该总是立即返回。

教导代码将0视为oop并继续下去并不难。但是我宁愿不要;我希望在这种情况下永远不会看到0,我想将其视为错误的证据。毕竟,如果反复发生,线程将旋转。 (在这种情况下将usleep(500)插入是一种黑客解决方案。)

问题是,这是否是内核中竞争条件的证据?还是该设备的驱动程序(这是标准的USB“串行”设备)引起的?基本上,我想知道向谁投诉,或者我是否有权投诉。在ppoll说要这样做之后,我永远都不会期望read从产生数据的设备返回0。

请注意,我使用相同的ppoll-read函数读取/ dev / random,并且它永远不会返回0。这与该USB设备有关。我已经对此进行了编码,因此我只是在寻求理解,而不是寻求解决。欢迎启蒙。

1 个答案:

答案 0 :(得分:0)

这个谜的答案是:我是个白痴。

我没有将文件句柄设置为原始模式。随机生成的字符被解释为行编辑,EOF和其他各种废话。读取计数相应地显得愚蠢;特别是EOF可以导致返回0个字节。