2017-10-31 9 views
1

このanswerによれば、そうではありません。しかしこれは私がこれまで見てきたものとは一致していません。次のスクリプトを考えてみましょう:Python - numpy.randomの関数呼び出しは安全ですか?

import numpy as np 
from multiprocessing.dummy import Pool 
from queue import Queue 

SIZE=1000000 
np.random.seed(1) 
tPool = Pool(100) 
q1 = Queue() 

def worker_thread(i): 
    q1.put(np.random.choice(100, 5)) 

tPool.map(worker_thread, range(SIZE)) 

q2 = Queue() 
np.random.seed(1) 
for i in range(SIZE): 
    q2.put(np.random.choice(100, 5)) 

n = 0 
for i in range(SIZE): 
    n += (q1.get() == (q2.get())) 

print(n) 

を、私はここでテスト通話のSIZE数は、シングルスレッド環境でのようなマルチスレッド環境で同じシーケンスを生成するかどうかですよ基本的にはどのような。私にとってこれはn = SIZEを出力します。もちろん、これはちょうどチャンスかもしれないので、私はそれを数回実行し、一貫した結果を持っています。だから私の質問は、スレッドセーフのnumpy.randomパッケージの関数への呼び出しですか?

答えて

1

自分のマシンでスクリプトを何度も実行し、、999992の配列を1000000(python 3.5.2、numpy 1.13.3)とほぼ同じくらい頻繁に使用しています。したがって、あなたが指している答えは正しいです:np.randommayマルチスレッド環境で異なる結果を生成します。

プールのサイズを大きくすると、1000、サンプルサイズは50になります。 SIZE=100000でも、100%の不一致を達成できました。

+0

これは奇妙です。私は3つの異なるマシンでPython 3.5.2とnumpy 1.13.3を実行してテストしました。スレッドプールを1000に増やしても、サンプルサイズを50に、サンプリング範囲を10'000に増やしても、 。どうすればいいの? – spurra

+0

興味深い。別のマシンでも試してみます。ネイティブ実装のように見えます。今、私はLinux、x86_64、カーネル4.10.0-37- genericを使用しています。 – Maxim

+1

@BananaCode私は、 'np.random'が他のマシンで実際に安定していることを確認できます。 Python 3.5.2と3.6.0、numpy 1.13.3と1.12.1を試しました。これは、 'libc'やカーネルバージョンにも依存すると私に思います。しかし、スレッドの安全性は保証されていません。 – Maxim

関連する問題