2017-02-02 26 views
1

我在Windows上使用Python 3.6,並且有一個可並行化的任務,其中包括計算字符串散列。這基本上是我的問題的最低版本:不同線程之間的Python哈希差異

#!/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,但我更願意找到一個代碼內解決方案)

+0

暫時的解決辦法,我現在是使用顯式哈希:'hashlib.md5(foo.encode()).hexdigest()' – Opossum

回答

1

正如你已經解釋的,散列隨機化可以用PYTHONHASHSEED來控制,欲瞭解更多信息請閱讀this。現在,如果你想通過代碼控制行爲,而不是使用python解釋器選項或導出env。 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

相關問題