tags:

views:

609

answers:

8

Hi,

I am writing a C++ program which needs to create a temporary file for its internal usage. I would like to allow concurrent executions of the program by running multiple proccesses, so the temporary file name needs to be randomized, that way each spawned process will generate a unique temporary file name for its own use. I am using rand() to generate random characters for part of the file name, so i need to initialize the random number generator's seed using srand(). What options are there for passing a good argument to srand() such that two processes will not be initialized with the same seed value? My code needs to work both on Windows and pn Linux

TIA.

+1  A: 

If you are trully just needing a temp file you can use:

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

Use time:

srand(time(NULL));

Also note that rand() probably is not thread safe.
So be careful how you use it. Two threads entering rand at the same time are going to cause problems.

Martin York
Is it `BULL` or `NULL` ;)
AraK
You forgot #define BULL NULL
codaddict
Thanks guys :-(
Martin York
@Martin York:If i spawn two proccesses in the same second they will both be started with the same seed. In fact even a resolution of milliseconds might night be good enough.Nice try, though.
zr
Isn't this precisely what you _don't_ want? The question explicitly stated that you want two concurrent processes, which implies two threads.
MSalters
@zr: If you are starting up by hand this is unlikely. If they are being started up by script put a sleep between the startup of the two processes. Or use rand(time(NULL)+10000) in one application.
Martin York
Concatenate time and PID.
SF.
if they're two processes, then you don't need to worry about concurrency of rand() because each will have their own copy of rand(). If they're two threads, then you have the problem you're talking about.
rmeador
@rmeador: And another award of "Captain Obvious". I think there should be a new badge called "Captain Obvious" that we can award to people that point out correct, but obvious to even the newest of noobs, advice.
Martin York
@SF: I like that. What about multiplying by PID is that going to gain anything additional?
Martin York
@Martin York: I was addressing @MSalter's apparent confusion on this issue.
rmeador
@Martin York: I'm sure that I'm stating the obvious (yes, that's sarcasm), but that's pretty subjective. What you consider obvious is not always obvious to noobs or even experienced folks. Why not just let such comments slide? ... eagerly awaiting my second "Captain Obvious" award.
Void
Captain Sarcasm badge for you :-( Slightly chastised.
Martin York
A: 

you could get the time in microseconds, and multiply it by a large number to get a seed. However, collisions can always happen, no matter what seed.

The Guy Of Doom
+23  A: 

The question is actually asking how to create a uniquely-named temporary file.

The operating system probably provides an API for this, which means you do not have to generate your own name.

On Windows, its called GetTempFileName() and GetTempPath().

On Unix, use tmpfile().

(Windows supports tmpfile() too; however, I've heard reports that from others that, whilst it works nicely on XP, it fails on Vista if you're on the C: drive and you are not an administrator; best to use the GetTempFileName() method with a custom, safe path)

Will
On POSIX it is mkstemp
Mark
Thanks. I was not aware of these API.
zr
It seems tmpfile is supported on Windows as well - http://msdn.microsoft.com/en-us/library/x8x7sakw.aspx
jschmier
I support this as a good answer, but I'll toss in the option of using a GUID for the filename.
Steven Sudit
+1 for answering the question that should have been asked.
Bill
A: 

On unix systems, read a value out of /dev/random

doron
A: 

Different processes will have different process IDs. However, adding that straight to the time would be a bit careless, as it's often a small number. It's not a big problem though: the underlying problem is that both the time and the process ID have their entropy concentrated in their lowest bits. By simply bit-reversing either and XOR'ing the result, you get good entropy in all bits.

MSalters
A: 

The function time from the time.h-library returns the number of seconds since the unix epoch, so if you don't need more granular seeds you might want to use it.

As time.h is a part of the C standard library, you can use it for both Linux and Windows.

drmegahertz
+1  A: 

I've never used it myself, but you might be able to use tmpnam() to generate your temporary file name. A quick search indicated support on both Windows and Linux.

jschmier
A: 

I would suggest that you do not use a random file name, but instead create a unique file name from the process id and the current time (if the time resolution you can read is sufficient for you, which it should be). I don't know enough about your problem, but I suspect that there is no benefit from using a random name, and the risk for collisions may be very real. This is true even if you use the operating system to create the files for you which was suggested in another answer.

Plow