2010-02-02 12 views
6

Estoy escribiendo un programa en C++ que necesita crear un archivo temporal para su uso interno. Me gustaría permitir las ejecuciones simultáneas del programa ejecutando múltiples procesos, por lo que el nombre del archivo temporal debe ser aleatorio, de esa manera cada proceso generado generará un nombre de archivo temporal único para su propio uso.Cómo generar una buena semilla aleatoria para pasar a srand()?

Estoy usando rand() para generar caracteres aleatorios para una parte del nombre del archivo, así que necesito inicializar la semilla del generador de números aleatorios usando srand().

¿Qué opciones existen para pasar un buen argumento a srand() para que dos procesos no se inicialicen con el mismo valor inicial? Mi código necesita funcionar tanto en Windows como en Linux.

Respuesta

24

La pregunta es en realidad preguntando cómo crear un archivo temporal con nombre único.

El sistema operativo probablemente proporciona una API para esto, lo que significa que no tiene que generar su propio nombre.

En Windows, se llama GetTempFileName() and GetTempPath().

En Unix, use tmpfile().

(Windows también admite tmpfile(); sin embargo, he escuchado informes de otros que, si bien funciona bien en XP, falla en Vista si está en la unidad C: y usted no es un administrador; utilizar el método GetTempFileName() con una costumbre, camino seguro)

+3

En POSIX es mkstemp – Mark

+0

Gracias. No tenía conocimiento de estas API. –

+0

Parece que el archivo tmp también es compatible con Windows - http://msdn.microsoft.com/ es-us/library/x8x7sakw.aspx – jschmier

2

Si os deis sólo necesitan un archivo temporal que puede utilizar:

FILE* tmpfile();  // Generate an unnamed temporary file. 
char* tmpnam(char* s); // Generate a file name in the director specified by TMPDIR 

Uso tiempo:

srand(time(NULL)); 

También tenga en cuenta que rand() probablemente no es seguro para subprocesos.
Así que ten cuidado cómo lo usas. Dos hilos que entran en rand al mismo tiempo van a causar problemas.

+1

¿Es '' BULL' o null';) – AraK

+2

Usted olvidó BULL #define NULL – codaddict

+0

Gracias chicos :-( –

0

puede obtener el tiempo en microsegundos y multiplicarlo por un número grande para obtener una semilla. Sin embargo, las colisiones siempre pueden ocurrir, sin importar qué semilla.

0

en sistemas UNIX, leer un valor de /dev/random

0

procesos diferentes tendrán diferentes identificadores de proceso. Sin embargo, agregar eso directamente al tiempo sería un poco descuidado, ya que a menudo es un número pequeño. Sin embargo, no es un gran problema: el problema subyacente es que tanto el tiempo como el ID del proceso tienen su entropía concentrada en sus bits más bajos. Simplemente al invertir el bit y al ejecutar XOR, obtendrá una buena entropía en todos los bits.

0

La función time de la time.h -library devuelve el número de segundos desde the unix epoch, por lo que si no necesita semillas más granulares, es posible que desee utilizarla.

Como time.h es parte de la biblioteca estándar C, puede usarlo tanto para Linux como para Windows.

1

Nunca lo he usado, pero es posible que pueda usar tmpnam() para generar su nombre de archivo temporal.Una búsqueda rápida indicó compatibilidad en Windows y Linux.

0

Sugiero que no utilice un nombre de archivo aleatorio, sino que cree un nombre de archivo único a partir de la identificación del proceso y la hora actual (si la resolución de tiempo que puede leer es suficiente para usted, que debería ser) . No sé lo suficiente acerca de su problema, pero sospecho que no se beneficia el uso de un nombre al azar, y el riesgo de colisiones puede ser muy real. Esto es cierto incluso si utiliza el sistema operativo para crear los archivos para usted que se sugirieron en otra respuesta.

Cuestiones relacionadas