阻塞Linux的read(2)函数,直到所有count字节都到达

4

我正在使用read(2)来从一个文件(/dev/random, 数据到达非常缓慢)读取内容。

然而,read()只能读取很少的字节就返回了,但我希望它等到读取完指定数量的字节或出现错误后再返回,所以返回值应该始终为计数,否则为-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个回答

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个字节。如果您拥有超级用户权限,可以增加此值,但我认为将其增加到1024并期望您的计算机正常工作可能相当乐观。我不知道需要一点熵的所有内容,但我肯定已经注意到我的熵池上下波动,因此我知道某些东西需要它,我强烈怀疑任何需要熵的东西都不会希望等待1024位的可用熵。总之,现在您有了一点自主权...


3

虽然在接收到请求的数据之前,读取操作可以被信号中断,但是无法在没有while循环的情况下完成读取操作。

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


+1,而且既然这是/dev/random,多进行几次读取调用也不会拖慢你的速度。 - FatalError

0
根据文档,/dev/random尽力返回最可靠的随机数据,并限制一次读取返回的字节数。
但是读取/dev/urandom(注意'u')将返回您请求的所有数据(缓冲区大小),有时会返回较少的随机数据。
这里是一个有用的链接
关于read()的行为,我非常确定它无法更改:read()返回底层管道(例如磁盘+驱动程序+...)决定返回的数据量,这是一种设计行为。做事情的方法就像你说的那样,循环直到收到预期的数据量。

这可靠吗?read 可能会被信号中断,源类型是否保证在调用结束之前不会出现这样的信号? - Piotr Zierhoffer
我需要真正的随机数据。此外,我认为从/dev/urandom读取不保证总是会读取count字节,只是更有可能。 - mic_e
我认为是的,这是有保证的。无论如何,如果你想让数据尽可能随机,你必须使用 /dev/random 并循环直到达到所需的字节数。很抱歉,但我真的非常认为你不能强制 read() 返回你想要的那么多数据。 - mbarthelemy
没错,理论上来说 urandomrandom 不太随机 ;-) - Piotr Zierhoffer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接