如何在多进程和多线程环境中生成随机唯一标识符?

Ger*_*ens 3 python sql mod-wsgi

我提出的每个解决方案都不是线程保存.

def uuid(cls,db):
    u = hexlify(os.urandom(8)).decode('ascii')
    db.execute('SELECT sid FROM sessions WHERE sid=?',(u,))
    if db.fetch(): u=cls.uuid(db)
    else: db.execute('INSERT INTO sessions (sid) VALUES (?)',(u,))
    return u
Run Code Online (Sandbox Code Playgroud)

Ale*_*lli 5

import os, threading, Queue

def idmaker(aqueue):
  while True:
    u = hexlify(os.urandom(8)).decode('ascii')
    aqueue.put(u)

idqueue = Queue.Queue(2)

t = threading.Thread(target=idmaker, args=(idqueue,))
t.daemon = True
t.start()

def idgetter():
  return idqueue.get()
Run Code Online (Sandbox Code Playgroud)

队列通常是在Python中同步线程的最佳方式 - 这种频率足以在设计多线程系统时首先想到的是"我怎样才能最好地使用队列".基本思想是将一个线程专用于完全"拥有"共享资源或子系统,并让所有其他"工作"线程仅通过获取和/或放置该专用线程使用的队列来访问资源(队列本质上是线程安全的) .

在这里,我们制作一个idqueue只有2的长度(我们不希望id生成变得狂野,事先制作了大量的id,浪费了内存并耗尽了熵池 - 不确定是否2是最佳的,但是甜蜜的spot肯定会是一个非常小的整数;-),所以id生成器线程在尝试添加第三个时会阻塞,并等到队列中有一些空格打开. idgetter(也可以简单地通过顶级作业来定义idgetter = idqueue.get)通常会在那里找到一个id并等待(并为下一个做出空间!) - 如果没有,它本质上会阻塞并等待,一旦醒来就会立即唤醒id生成器在队列中放置了一个新的id.