首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >uuid.uuid1、uuid_generate_time和线程

uuid.uuid1、uuid_generate_time和线程
EN

Stack Overflow用户
提问于 2014-07-29 02:16:48
回答 1查看 1.3K关注 0票数 3

在Python中,我可以始终在uuid模块中生成一个seg错误。这可以通过从多个线程重复调用uuid.uuid1()来实现。经过一番研究,看来这个函数最终通过ctypes调用了Cctypes函数

来自uuid.py:

代码语言:javascript
复制
for libname in ['uuid', 'c']:
    try:
        lib = ctypes.CDLL(ctypes.util.find_library(libname))
    except:
        continue
    if hasattr(lib, 'uuid_generate_random'):
        _uuid_generate_random = lib.uuid_generate_random
    if hasattr(lib, 'uuid_generate_time'):
        _uuid_generate_time = lib.uuid_generate_time
        if _uuid_generate_random is not None:
            break  # found everything we were looking for

以及uuid1()的定义。

代码语言:javascript
复制
def uuid1(node=None, clock_seq=None):
    """Generate a UUID from a host ID, sequence number, and the current time.
    If 'node' is not given, getnode() is used to obtain the hardware
    address.  If 'clock_seq' is given, it is used as the sequence number;
    otherwise a random 14-bit sequence number is chosen."""

    # When the system provides a version-1 UUID generator, use it (but don't
    # use UuidCreate here because its UUIDs don't conform to RFC 4122).
    if _uuid_generate_time and node is clock_seq is None:
        _buffer = ctypes.create_string_buffer(16)
        _uuid_generate_time(_buffer)
        return UUID(bytes=_buffer.raw)

我读过uuid_generate_time的手册页和uuid.uuid1的Python,没有提到线程安全。我认为这与它需要访问系统时钟和/或MAC地址这一事实有关,但这只是一个盲目的猜测。

,我想知道是否有人能启发我?

下面是我用来生成seg错误的代码:

代码语言:javascript
复制
import threading, uuid

# XXX If I use a lock, I can avoid the seg fault
#uuid_lock = threading.Lock()
def test_uuid(test_func):
  for i in xrange(100):
    test_func()
    #with uuid_lock:
    #  test_func()

def test(test_func, threads):
  print 'Running %s with %s threads...' % (test_func.__name__, threads)

  workers = [threading.Thread(target=test_uuid, args=(test_func,)) for x in xrange(threads)]
  [x.start() for x in workers]
  [x.join() for x in workers]
  print 'Done!'

if __name__ == '__main__':
  test(uuid.uuid4, 8)
  test(uuid.uuid1, 8)

我得到的输出是:

代码语言:javascript
复制
Running uuid4 with 8 threads...
Done!
Running uuid1 with 8 threads...
Segmentation Fault (core dumped)

哦,我在Solaris上运行这个..。

EN

回答 1

Stack Overflow用户

发布于 2014-07-29 04:46:02

文档没有说它是线程安全的,所以您不能假设它是安全的。事情就是这么简单。

查看当前的OpenIndiana源 for uuid_generate_time,并不完全清楚是什么导致了分段错误。然而,虽然函数确实使用了锁,但它在执行许多初始化任务时并不持有此锁。这可能与问题有关,但我不能指出比赛条件会导致错误的具体地点。在启动任何线程之前,您可以尝试调用uuid1一次,并查看这是否使问题消失。尽管您最好只使用自己的锁,因为不能保证Python代码本身是线程安全的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25007264

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档