views:

154

answers:

3

I'm trying to generate a uuid for a filename, and I'm also using the multiprocessing module. Unpleasantly, all of my uuids end up exactly the same. Here is a small example:

import multiprocessing
import uuid

def get_uuid( a ):
    ## Doesn't help to cycle through a bunch.
    #for i in xrange(10): uuid.uuid4()

    ## Doesn't help to reload the module.
    #reload( uuid )

    ## Doesn't help to load it at the last minute.
    ## (I simultaneously comment out the module-level import).
    #import uuid

    ## uuid1() does work, but it differs only in the first 8 characters and includes identifying information about the computer.
    #return uuid.uuid1()

    return uuid.uuid4()

def main():
    pool = multiprocessing.Pool( 20 )
    uuids = pool.map( get_uuid, range( 20 ) )
    for id in uuids: print id

if __name__ == '__main__': main()

I peeked into uuid.py's code, and it seems to depending-on-the-platform use some OS-level routines for randomness, so I'm stumped as to a python-level solution (to do something like reload the uuid module or choose a new random seed). I could use uuid.uuid1(), but only 8 digits differ and I think there are derived exclusively from the time, which seems dangerous especially given that I'm multiprocessing (so the code could be executing at exactly the same time). Is there some Wisdom out there about this issue?

A: 

I dont see a way to make this work either. But you could just generate all the uuids in the main thread and pass them to the workers.

THC4k
A: 

This works fine for me. Does your Python installation have os.urandom? If not, random number seeding will be very poor and would lead to this problem (assuming there's also no native UUID module, uuid._uuid_generate_random).

Glenn Maynard
This is on Mac OS X (10.6.3, if it matters). I tested and it works fine on my Ubuntu machine. Both have os.urandom.
yig
+2  A: 

This is the correct way to generate your own uuid4, if you need to do that:

import os, uuid
return uuid.UUID(bytes=os.urandom(16), version=4)

Python should be doing this automatically--this code is right out of uuid.uuid4, when the native _uuid_generate_random doesn't exist. There must be something wrong with your platform's _uuid_generate_random.

If you have to do this, don't just work around it yourself and let everyone else on your platform suffer; report the bug.

Glenn Maynard
Sure enough, setting uuid._uuid_generate_random = None does the right thing. Must be a bug in Mac OS X's libc uuid_generate_random(). Thanks for the suggestion to file a bug report: http://bugs.python.org/issue8621
yig
I also filed a platform bug against Mac OS X: http://openradar.appspot.com/radar?id=334401
yig