阻止Linux读取(2)直到所有计数字节都到达

时间:2012-09-28 12:54:05

标签: c linux file system-calls blocking

我使用read (2)来读取文件(/dev/random,其中数据到达非常缓慢)。

但是,read()在读取几个字节后返回,而我希望它等到读取指定的字节数(或发生错误),因此返回值应始终为count,或-1。

有没有办法启用此行为? open (2)read (2)联机帮助页不包含有关该主题的任何有用信息,也未在互联网上找到有关该主题的任何信息。

我完全了解将read()放入while循环并调用它直到读取所有数据的解决方法。我想知道这是否可以以适当的方式实现,产生确定性行为,并且只涉及O(1)系统调用,而不是在while循环解决方案中的非确定性O(n)。

以下最小示例再现了该问题。

#include <stdio.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main() {
        int fd = open("/dev/random", 0);

        char buf[128];
        size_t bytes = read(fd, buf, sizeof(buf));

        printf("Bytes read: %lu\n", bytes); //output is random, usually 8.

        close(fd);
}

3 个答案:

答案 0 :(得分:3)

虽然在接收到请求的数据之前信号可能会中断读取,但如果没有,就无法完成。

不幸的是,您必须检查返回值和计数字节。 是的,最简单的方法是编写一个包装函数。

答案 1 :(得分:3)

正如大家所说,

  • 在您的读取返回之前,无法保证128字节的随机性可用,并且

  • 与生成8个字节的分摊成本相比,一次获取8个字节所涉及的开销是微不足道的。因此,

  • 你应该记住熵是一笔巨大的费用,并在消费时考虑到这一点。

尽管如此,如果没有注意到man 4 random(在一个模糊的Linux发行版上)你应该找到以下信息,那么这个问题的答案就不会完整:

The files in the directory /proc/sys/kernel/random
(present since 2.3.16) provide an additional interface
to the /dev/random device.

...

The file read_wakeup_threshold contains the number of bits of
entropy required for waking up processes that sleep waiting
for entropy from /dev/random. The default is 64.

即64个,即8个字节。使用超级用户权限,您可以增加此值,但imho将其增加到1024,然后期望您的机器保持正常工作可能相当乐观。我不知道所有需要一些熵的东西,但我当然注意到我的熵池上下起伏,所以我知道有些东西需要它而且我强烈怀疑无论什么东西都不会高兴不得不等待它的1024位可用。无论如何,你知道有一点绳子......

答案 2 :(得分:0)

从文档中,/ dev / random尽力返回最可靠的随机数据,并限制它在一次读取时返回的字节数。

但是读取/ dev / urandom(注意'u')将返回所请求的数据(缓冲区大小),有时候随机数据会减少。

这是an useful link

关于read()行为,我很确定无法更改:read()返回基础plumbery(例如disk + driver + ...)决定返回的数据量,它是 - 设计行为。正如你所说,做事的方法是循环,直到你收到尽可能多的数据。