[TriLUG] Aligning of the crazy numbers
oberry at trilug.org
Thu Aug 17 14:20:34 EDT 2006
On Thu, Aug 17, 2006 at 01:59:53PM -0400, Josh Vickery wrote:
> Well, if you are reading from /dev/urandom, why not read from a file
> with a counter in it instead?
I'm not explicitly reading from /dev/urandom, I'm calling the Perl rand
function, which calls srand if it hasn't been seeded, which will use
/dev/urandom if it's there.
> You can then use file locking to make sure that only one instance at
> time reads from it, and you can be guaranteed that the numbers do not
> overlap. If that won't work, you could use file locking on
> /dev/urandom. Get an exclusive lock before you seed the generator,
> then release it after its been seeded.
I wanted to avoid the extra complexity of locking - low tech solution
*usually* works best - and I'd like to keep it that way.
> This won't guaranty that you won't get duplicates though, because
> urandom could still spit out the same number twice in a row.
Good point. I guess I took my chances with the fact that it was very
unlikely to happen in the same microsecond. Especially since the unique
id also contains the "login" of the user, making it even less likely,
*unless* the're running a multithreaded query engine (this isn't a
typical web application).
> The PID bit would help, but wouldn't work if the program uses multiple
Nope, single threaded CGI application. And a simpler solution than
creating exclusive locks.
BTW, this (http://lkml.org/lkml/2004/11/27/120) LKML thread indicates
that at one stage there was a locking problem with /dev/urandom with the
2.4 kernel on multi CPU machines. Multithreaded applications could read
the same data off /dev/urandom in separate threads reasonably regularly.
This particular machine is RHEL3 with 2.4.21 kernel. Wonder if the bug
exists there. Just a bit of trivia, and ponderings.
> On 8/17/06, Owen Berry <oberry at trilug.org> wrote:
> >I have a CGI program that needs to generate a unique identifier each
> >time it gets executed. The problem is that it can get executed multiple
> >times per second (duh ... CGI), and requirements limit me from having a
> >central source from which to generate a unique id. Besides, I have a
> >much simpler solution ... well I thought I did. Take the time in seconds
> >since the beginning of the epoch, the number of microseconds in the
> >current second, and a 3 digit random number, and concatenate them
> >together with delimiters. Sounds reasonable, right? Maybe even a little
> >excessive with the random number. Well, 3 times in the past month we've
> >seen the same id generated by 2 requests running simultaneously!
> >It's Perl code, but according to the documentation the seconds and
> >microseconds are grabbed using the standard gettimeofday system
> >function, and the random number generator is seeded by /dev/urandom. So
> >they should both work pretty well, and seem to when tested.
> >The only partial explanation I can think of is that this is a dual CPU
> >system and both requests were literally running at the same time, down
> >to the microsecond. Anyone know if there is any locking on /dev/urandom
> >to prevent 2 processes grabbing the same data at the same time?
> >Anyway, I have a simple solution ... add the process id to the mix. That
> >should be unique amongst concurrently executing processes, right? ;-)
More information about the TriLUG