【问题标题】:Python hashes differ between threads线程之间的 Python 哈希值不同
【发布时间】:2017-02-02 10:35:09
【问题描述】:

我在 Windows 上使用 Python 3.6,并且有一个可并行化的任务,其中包括计算字符串哈希。这基本上是我的问题的最小版本:

#!/usr/bin/env python3
from joblib import Parallel, delayed


def hash_some(foo):
    return hash(foo)


def main():
    hashes = Parallel(n_jobs=10)(delayed(hash_some)(s) for s in ['a', 'a', 'a'])

    print(hashes)


if __name__ == '__main__':
    main()

现在,由于某种原因,这会打印出来,例如:

[3220780809080710068, -561460911962106608, -1551910331007446174]

它们显然应该都是一样的。

哈希值并不总是不同,尤其是对于较低的 n_job 值,它们通常结果相同,但这不能保证。

我知道hash() 在每次程序调用时使用随机种子,但为什么它显然在每个线程中使用不同的种子?有什么方法可以为我的所有线程设置一个固定(但随机)的种子? (我知道PYTHONHASHSEED=0,但我更愿意找到代码内解决方案)

【问题讨论】:

  • 我现在的临时解决方法是使用显式哈希:hashlib.md5(foo.encode()).hexdigest()

标签: python hash concurrency parallel-processing


【解决方案1】:

正如您已经解释的那样,可以使用 PYTHONHASHSEED 控制哈希的随机化,有关更多信息,请阅读 this。现在,如果您想通过代码控制行为,而不是使用 python 解释器选项或导出该环境。 var 一个可能的解决方案可能是这样的:

#!/usr/bin/env python3
import random
import os
from joblib import Parallel, delayed

os.environ['PYTHONHASHSEED'] = '0'

def hash_some(foo):
    return hash(foo)

def main():
    hashes = Parallel(n_jobs=10)(delayed(hash_some)(s) for s in 'a' * 10000)

    print(set(hashes))

if __name__ == '__main__':
    main()

如果您评论 os.environ 行,您会看到最终设置的长度将不再是 1

【讨论】:

    猜你喜欢
    • 2013-04-13
    • 2012-05-20
    • 1970-01-01
    • 2023-02-19
    • 1970-01-01
    • 1970-01-01
    • 2011-05-17
    • 2018-03-23
    相关资源
    最近更新 更多