如何在多进程多线程环境中生成随机唯一标识符? [英] How do you generate random unique identifiers in a multi process and multi thread environment?

查看:101
本文介绍了如何在多进程多线程环境中生成随机唯一标识符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Every solution I come up with is not thread save.

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

推荐答案

你的算法没问题(只要你的 DB API 模块是安全的,线程安全)并且可能是最好的方法.它永远不会给你重复(假设你在 sid 上有 PRIMARY 或 UNIQUE 键),但你有一个被忽略的小机会在 INSERT 上获得 IntegrityError 异常.但是你的代码看起来不太好.最好使用尝试次数有限的循环而不是递归(如果代码中出现某些错误可能会变得无限):

Your algorithm is OK (thread safe as far as your DB API module is safe) and probably is the best way to go. It will never give you duplicate (assuming you have PRIMARY or UNIQUE key on sid), but you have a neglectfully small chance to get IntegrityError exception on INSERT. But your code doesn't look good. It's better to use a loop with limited number of attempts instead of recursion (which in case of some error in the code could become infinite):

for i in range(MAX_ATTEMPTS):
    sid = os.urandom(8).decode('hex')
    db.execute('SELECT COUNT(*) FROM sessions WHERE sid=?', (sid,))
    if not db.fetchone()[0]:
        # You can catch IntegrityError here and continue, but there are reasons
        # to avoid this.
        db.execute('INSERT INTO sessions (sid) VALUES (?)', (sid,))
        break
else:
    raise RuntimeError('Failed to generate unique session ID')

您可以增加读取的随机字符数,使失败的几率更小.base64.urlsafe_b64encode() 如果您想让 SID 更短,则是您的朋友,但是您必须确保您的数据库对此列使用区分大小写的比较(MySQL 的 VARCHAR 不适合,除非您设置二进制排序规则,但 VARBINARY 是可以的).

You can raise the number of random characters read used to make chance to fail even smaller. base64.urlsafe_b64encode() is your friend if you'd like to make SID shorter, but then you have to insure your database uses case-sensitive comparison for this columns (MySQL's VARCHAR is not suitable unless you set binary collation for it, but VARBINARY is OK).

这篇关于如何在多进程多线程环境中生成随机唯一标识符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆