Python多进程与uuid.uuid4()不兼容。

8

我正在尝试为文件名生成UUID,并且我还在使用多进程模块。不幸的是,我的所有UUID最终都完全相同。这里有一个小例子:

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

我查看了uuid.py的代码,它似乎依赖于平台使用一些操作系统级别的随机数生成函数,因此我对Python级别的解决方案感到困惑(比如重新加载uuid模块或选择一个新的随机种子)。 我可以使用uuid.uuid1(),但只有8位数字不同,并且我认为这些数字仅来源于时间,这似乎很危险,特别是考虑到我正在进行多进程处理(因此代码可能在完全相同的时间执行)。是否有关于这个问题的智慧?
4个回答

5

如果需要生成自己的uuid4,以下是正确的方法:

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

Python应该自动完成这个过程——这段代码直接从uuid.uuid4中复制而来,当本地的_uuid_generate_random不存在时。你所使用的平台的_uuid_generate_random可能存在问题。

如果你不得不这样做,请不要只是自己解决问题,让你所在平台上的其他人也受苦;报告这个错误


1
果然,将uuid._uuid_generate_random设置为None就能达到预期的效果。这一定是Mac OS X libc uuid_generate_random()的一个bug。感谢您建议提交错误报告:http://bugs.python.org/issue8621。 - yig
我还在Mac OS X上提交了一个平台错误报告:http://openradar.appspot.com/radar?id=334401 - yig

0

目前,我正在编写一个脚本,从zip归档或磁盘中获取文件。获取后,有效载荷通过Web API推送到外部工具。

出于性能原因,我使用了multiprocessing.Pool.map方法。对于tmp文件名,uuid看起来非常方便。但是我遇到了你在这里提出的同样问题。

首先,请查看uuid的官方文档。有一个名为is_safe的类属性,如果uuid是多进程安全的,则提供更多信息。在我的情况下,它不是。

经过一些研究,我最终改变了策略,从uuid转向进程pid和名称。因为我只需要uuid用于临时文件命名,pid和名称也可以正常工作。我们可以通过multiprocessing.current_process()访问当前工作进程Process实例。如果您真的需要一个uuid,您可以尝试将工作进程pid集成在某种方式中。

此外,uuid使用系统进行生成(uuid源)。因为对我来说文件名的具体内容并不重要,这种解决方案还可以防止泄漏。

0

我也没有看到让它工作的方法。但是你可以在主线程中生成所有uuid,并将它们传递给工作线程。


0

这对我来说很好用。 你的 Python 安装是否有 os.urandom?如果没有,随机数种子将非常差,会导致这个问题(假设没有本地 UUID 模块,uuid._uuid_generate_random)。


这是在Mac OS X上(如果有关系的话,是10.6.3)。我测试过,在我的Ubuntu机器上运行良好。两者都有os.urandom。 - yig

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接