2011-12-24 14 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); 
} 

Imprime el mismo número (diferente en cada ejecución) 10 veces - ¿esperado? I tienen una pieza más complicada de código en cada proceso de horquilla se ejecuta a su vez - ninguna diferencia¿Por qué rand() no es tan aleatorio después del tenedor?

+0

Muchas gracias por las respuestas, claro ahora :) –

Respuesta

18

Las salidas deben ser lo mismo. Si dos procesos cada semilla el número aleatorio con la misma semilla y cada llamada rand una vez, debe obtener el mismo resultado. Ese es el punto de tener una semilla. Todos sus procesos llaman al srand con la misma inicialización (porque solo llama al srand una vez) y todos llaman al rand una vez, por lo que deben obtener el mismo resultado.

Sin importar el srand no hará la diferencia porque a menos que el número de segundos haya cambiado, todavía darán la misma semilla. Se podría hacer:

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

La función rand() es un generador de pseudo-aleatoria número. Esto significa que la secuencia de números generados es determinista, dependiendo únicamente de la semilla provista.

Dado que está bifurcando el mismo proceso 10 veces, el estado del generador de números aleatorios es el mismo para cada niño. La próxima vez que llame al rand() obtendrá el mismo valor.

Llamando srand(time(NULL)) dentro del proceso hijo, que son potencialmente ayudar pero la granularidad de time() es de sólo 1 segundo, por lo que todos sus hijos probablemente se originan dentro del mismo segundo. Sembrar con el mismo valor genera la misma secuencia pseudoaleatoria.

usted podría intentar la siembra con un valor que depende del número de hijos:

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

(he usado i*2 en el caso de que time() avances en 1 segundo durante el bucle tenedor.)

+0

En general, es una buena idea, pero sería conveniente incorporar el número de niño de una manera mucho más significativa. 'time (NULL) + 100 * i' o algo similar para garantizar una diferencia de uno o dos segundos no influirá en la semilla. – sarnold

+0

Buen punto, me gusta la idea de David Schwartz de usar el niño pid. –

+0

Sí, realmente me gustó cómo lo mezcló en _high_, también, pero con aplicaciones que 'clone (2)' en lugar de 'fork (2)' sería posible que todos tengan el mismo 'pid' pero diferente valores para 'i'. Ligera diferencia de matices que quizás nunca importe a nadie ... – sarnold

0

La razón porque esto se debe a que todos los programas tienen el mismo valor (fuera de ese ciclo while). Deberá volver a inicializar una vez que haya bifurcado el nuevo programa o ambos producirán la misma secuencia.

5

Si su código se está ejecutando lo suficientemente rápido, srand() podría sembrarse exactamente al mismo tiempo para cada horquilla. time() solo cambia cada segundo.

0

No está resiembrando cuando realiza un proceso secundario. El estado del generador de números aleatorios es exactamente el mismo.

Incluso si vuelve a sembrar en su hijo, está iniciando con el tiempo con una granularidad de +/- 1 segundo. Cuando te bifurcas, todo sucede en menos de un segundo.

Prueba sembrarlo con algo diferente y más aleatorio.

2

La razón por la que incluso la adición de srand(time(NULL)); (la línea dentro del bloque if que ha comentado) en el interior del bucle no está haciendo la diferencia se debe a que los ordenadores modernos pueden ejecutar todo ese bloque extremadamente rápido, y time cuenta en segundos. Desde las páginas de manual:

tiempo() devuelve el tiempo que el número de segundos desde la época ...

Si agrega un sleep(1); después de la declaración if en el bucle while y elimine el comentario srand llamada, los resultados serán diferentes, ya que time ahora devolverá un valor diferente porque ha transcurrido un segundo.

Sin embargo, sería más apropiado utilizar un valor de inicialización diferente, en lugar de esperar.Algo como i sería una buena idea ya que será único para cada iteración del ciclo.

0

Esto resuelve el problema:

srand48((long int)time(NULL)); 
i= (lrand48()/rand()+1) % 123 

No he probado con un tenedor, pero dentro de una para llamar 100 veces funciona.

semilla con el número pid. Es un problema pequeño pero difícil de resolver.

Esto fue en alguna página: "esto funcionó srand (time (0) + getpid()), pero tuve que llamar esto dentro del caso 0 es un proceso secundario".

+0

No entiendo tu inglés –