2011-12-24 7 views
10
#include <unistd.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

int main() { 
    int i =10; 
    /* initialize random seed: */ 
    srand(time(NULL)); 
    while(i--){ 
     if(fork()==0){ 
      /* initialize random seed here does not make a difference: 
      srand(time(NULL)); 
      */ 
      printf("%d : %d\n",i,rand()); 
      return; 
     } 
    } 
    return (EXIT_SUCCESS); 
} 

同じ(実行ごとに異なる)番号を10回印刷しますか?差がないなぜfork後にrand()がランダムでないのですか?

+0

お返事ありがとうございます - 今すぐクリア:) –

答えて

18

出力は、と同じでなければなりません。 2つのプロセスがそれぞれ同じシードの乱数をシードし、それぞれrandを呼び出すと、と同じ結果になる必要があります。それは種を持っている全体のポイントです。すべてのプロセスはsrandと同じシード(srandを1回しかコールしないため)を呼び出し、すべてrandを呼び出します。したがって、に同じ結果が必要です。

srandのコメントを外しても、秒数が変更されていない限り同じシードが返されます。

srand(time(NULL)^(getpid()<<16)); 
5

rand()関数は擬似ランダム数発生器である - Iは、各二股処理が順番に実行されるコードのより複雑な部分を有しています。これは、生成された数字のシーケンスが、提供されたシードのみに依存して決定論的であることを意味します。

同じプロセスを10回フォークするので、乱数ジェネレータの状態は各子に同じです。次回にrand()に電話すると、同じ値が得られます。子プロセスの内部で、あなたが潜在的にを支援しているが、time()の粒度はわずか1秒であるので、すべてのあなたの子供は、おそらく同じ秒内で開始srand(time(NULL))を呼び出すことによって

。同じ値でシードすると、同じ疑似ランダムシーケンスが生成されます。

あなたは子供の数に依存する値で播種試みることができる:

srand(time(NULL) - i*2); 

(私はフォークループ中に1秒ずつtime()進歩した場合にi*2を使用していました。)

+0

全体的には良いアイデアですが、はるかに重要な方法で子番号を組み込むことをお勧めします。 'time(NULL)+ 100 * i'または1〜2秒の差異が種子に影響しないようにするために類似した何か。 – sarnold

+0

良い点は、デビッド・シュワルツの子供のピッド使用の考えが好きです。 –

+0

ええ、私は彼が_high_でそれをどのように混在させるのか本当に好きでしたが、 'fork(2)'の代わりに 'clone(2)'を使うアプリケーションでは、 'pid' 「i」の値。誰にも決して重要でないかもしれないわずかなニュアンスの違い... – sarnold

0

理由これは、すべてのプログラムが同じ値(ループの外側)でシードされるからです。あなたが新しいプログラムをフォークしたら、再度シードするか、どちらも同じシーケンスを生成します。

5

コードが十分に速く実行されている場合は、srand()に各フォークとまったく同じ時刻が設定されている可能性があります。 time()は1秒ごとに変更されます。

0

子プロセスを作成するときに再シッピングすることはありません。乱数ジェネレータの状態はまったく同じです。

あなたの子供にもう一度播種しても、時間は+/- 1秒の粒度で播種しています。フォークすると、すべてが1秒未満で実行されます。

これとは違ったランダムなものを試してみてください。

2

現代のコンピュータがブロック全体を非常に高速で実行できるため、ループ内にsrand(time(NULL));(コメント中のブロック内の行)を追加しても違いがない理由は、time秒です。 manページから:

時間は()エポックからの秒数として時間を返します...

あなたはwhileループ内if文の後sleep(1);を追加して、コメントを解除した場合srandコールの場合、timeは秒が経過したために異なる値を返すため、結果は異なります。

ただし、待機するのではなく、別のシード値を使用する方が適切です。iのようなものは、ループの繰り返しごとに一意になるため、良い考えです。

0

は、この問題を解決:あなたは何ができる

srand48((long int)time(NULL)); 
i= (lrand48()/rand()+1) % 123 
私はフォークでテストhaventは

が、内部のそれが動作100回を呼び出します。

シード番号。問題を解決するのは少し難しいですが。

「これはsrand(time(0)+ getpid())で処理されましたが、ケース0の子プロセス内でこれを呼び出す必要がありました。

+0

私はあなたの英語を理解できません –

関連する問題