4

私はread (2)ファイルから読み取るために使用しています(/dev/randomデータの到着が非常に遅い場合)。

ただし、read()は数バイトを読み取った後に返されますが、指定されたバイト数が読み取られるまで(またはエラーが発生するまで)待機したいので、戻り値は常にcount、つまり-1である必要があります。 。

この動作を有効にする方法はありますか?open (2)およびマンページには、そのトピックに関する有用な情報は含まれていません。read (2)また、インターネット上でそのトピックに関する情報も見つかりませんでした。

私はread()、whileループの内側に配置し、すべてのデータが読み取られるまでそれを呼び出すという回避策を十分に認識しています。これが、whileループソリューションの場合の非決定論的O(n)ではなく、決定論的動作を生成し、O(1)システムコールのみを含む適切な方法で達成できるかどうかを知りたいだけです。

次の最小限の例は、問題を再現します。

#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

要求されたデータが受信される前に、信号によって読み取りが中断される可能性がありますが、実際にはしばらくの間でないと実行できません。

残念ながら、戻り値を確認してバイト数をカウントする必要があります。はい、最も簡単な方法は、ラッピング関数を作成することです。

于 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ビット、つまり 8 バイトです。スーパーユーザー権限を使用すると、この値を増やすことができますが、1024 に増やして、マシンが通常どおり動作し続けることを期待するのは、おそらくかなり楽観的です。少しのエントロピーを必要とするすべてのことを知っているわけではありませんが、エントロピープールが上下することに確かに気づいたので、何かがそれを望んでいることは知っています。 1024 ビットが使用可能になるまで待ちます。とにかく、あなたは少しロープを持っていることを知っています...

于 2012-09-29T02:51:19.843 に答える
0

ドキュメントによると、 /dev/random は可能な限り最も信頼性の高いランダム化されたデータを返すために最善を尽くしており、1 回の読み取りで返されるバイト数を制限しています。

しかし、/dev/urandom (「u」に注意してください) を読み取ると、要求した (バッファー サイズ) と同じ量のデータが返されますが、ランダム化されたデータが少なくなる場合があります。

ここに便利なリンクがあります

read() の動作については、これは変更できないと確信しています。read() は、基になる配管 (たとえば、ディスク + ドライバー + ...) が返すことを決定したデータの量を返します。これは設計上の動作です。あなたが言ったように、物事を行う方法は、期待どおりのデータを受け取るまでループすることです。

于 2012-09-28T13:01:29.020 に答える