4

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

但是, read() 只读取几个字节后返回,而我希望它等到读取指定数量的字节(或发生错误),所以返回值应该始终是 count 或 -1 .

有没有办法启用这种行为?open (2)read (2)手册页不包含有关该主题的任何有用信息,我也没有在 Internet 上找到有关该主题的任何信息。

我完全知道将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);
}
4

3 回答 3

3

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

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

于 2012-09-28T13:00:59.337 回答
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 bits,也就是八个字节。使用超级用户权限,您可以增加此值,但恕我直言,将其增加到 1024,然后期望您的机器继续正常工作可能是相当乐观的。我不知道所有需要一点熵的东西,但我当然注意到我的熵池会上下波动,所以我知道有些东西想要它,我强烈怀疑无论是什么东西都不会高兴不得不等待它的 1024 位可用。无论如何,你知道有一点绳子......

于 2012-09-29T02:51:19.843 回答
0

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

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

这是一个有用的链接

关于 read() 行为,我很确定这是无法更改的: read() 返回底层管道(例如磁盘+驱动程序+ ...)决定返回的数据量,这是一种设计行为。正如您所说,做事的方法是循环直到您收到与预期一样多的数据。

于 2012-09-28T13:01:29.020 回答