7
votes

Python MultiProcessing ne joue pas bien avec UUID.UUID4 ()

J'essaie de générer un UUID pour un nom de fichier et j'utilise également le module multiprocessivant. Désagréablement, tous mes uuids finissent exactement la même chose. Voici un petit exemple:

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()


0 commentaires

4 Réponses :


0
votes

Je ne vois pas un moyen de faire ce travail non plus. Mais vous pouvez simplement générer tous les uuids dans le fil principal et les transmettre aux travailleurs.


0 commentaires

0
votes

Cela fonctionne bien pour moi. Votre installation Python a-t-elle Os.urandom? Sinon, l'ensemencement au nombre aléatoire sera très pauvre et conduira à ce problème (en supposant qu'il n'y a pas non plus de module UUID natif, uuid._uuid_generate_random).


1 commentaires

Ceci est sur Mac OS X (10.6.3, si cela compte). J'ai testé et ça marche bien sur ma machine Ubuntu. Les deux ont os.urandom.



5
votes

C'est la bonne façon de générer votre propre uuid4, si vous devez le faire:

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


2 commentaires

Bien sûr, définir uuid._uuid_generate_random = aucun ne fait la bonne chose. Doit être un bug dans la libc uuid_generate_random (). Merci pour la suggestion de déposer un rapport de bogue: bugs.pytthon.org/issue8621


J'ai également déposé un bug de plate-forme sur Mac OS X: openradar.appspot.com/radar?id=334401



0
votes

Actuellement, je travaille sur un script, qui récupère un fichier d'une archive ou d'un disque zip. Après avoir récupéré, la charge utile est poussée à un outil externe via une API Web. Pour la raison de la performance, j'ai utilisé le multiprocessing.pool.map méthode. Et pour le nom de fichier TMP uuid semblait assez pratique. Mais j'ai couru dans le même problème que vous avez demandé ici.

Tout d'abord, veuillez consulter les documents officiels de UUID . Il y a un attribut de classe appelé is_safe qui fournit plus d'informations si l'UUID est multiprocessé ou non. Dans mon cas, ce n'était pas.

Après quelques recherches, j'ai enfin changé ma stratégie et déplacé d'UUID pour traiter PID et nom. Parce que j'ai juste besoin de l'UUID pour le nom de fichier TMP, le PID et le nom fonctionnent également bien. Nous pouvons accéder au travailleur actuel processus instance via multiprocessing.Current_process ( ) . Si vous avez vraiment besoin d'une UUID, vous pouvez potentiellement intégrer le travailleur pid en quelque sorte.

En outre, UUID utilise le système entropie pour la génération ( Source UUID ). Parce que pour moi, peu importe la manière dont le fichier est nommé, cette solution empêche également le frottement entropie .


0 commentaires