2016-07-30 1 views
0

私は比較的新しいPythonですが、少し熟練しています。この小さなコードが私を狂わせてしまいます。なぜ地球上にあるのですかsumme()スレッドでこんなに頑固なのですか?スレッドはの順にのように処理されているようです。つまり、次のすべてのスレッドは、前のスレッドが終了した場合にのみ開始されます。どうしてか分かりません? 4つのスレッドはすべて「並列に」開始し、「並列に」動作する必要があります。 GILという制限のために、1つのコアでのみ実行されていても。計算量の多いスレッドはPython 3で「ぶら下がっている」 - なぜですか?

count()の手順は、同じように「並行して」となります。 !

によりGILへの親愛なるインターネット、私を助けてください...

ポール:)

#!/usr/bin/python3 

import threading 

# Hanging... 
def summe(n): 
    print("Start") 
    s = sum(range(n)) 
    print("Done") 

# Works like a charm 
def count(n): 
    print("Start") 
    while n > 0: 
     n = n-1 
    print("Done") 

# This works 
for i in range(3): 
    threading.Thread(target=count,args=(10000000000000,)).start() 

# This hangs... 
for i in range(3): 
    threading.Thread(target=summe,args=(10000000000000,)).start() 

答えて

1

sumのような組み込み関数は原子です。開始すると、完了するまで中断されません。 が可能ですが、スレッドシステムは、次のスレッドを開始できるようにコンテキストを切り替える前にsummeの最初の行のみを実行することを選択できますが、それはほとんどあり得ません。表示される「ハング」は、最後に完了するまでブロックされている最初のスレッドでsumです。一方、countには、GILをブロックする1つの長いアトミック操作はありません。小規模なオペレーションの多く(そしてロットとロット)は、各スレッドを開始してメインスレッドに戻るチャンスを与えます。 nのほうがはるかに小さい値を使用すると、countスレッドの開始を確認できます。その後、数分後に完了します。同様に、3つのsummeスレッドがほぼ連続して実行されていることがわかります(1回のテストでは、最初は実行されてから残りの2つが並行して実行されます)。

+0

非常に速い答えに感謝します。私の問題は、実際のメソッド(sum()は単なる例に過ぎない)です。私はCythonで書かれています。そのようなメソッドをアトミ​​ックではないように強制する方法はありますか? – Paulquappe

+0

@Paulquappe Cythonの機能を並列化する方が良いかもしれません。あなたのPython API呼び出しを取り除くことができれば、OpenMPを使ってGILを解放し、適切な並行性を実装することができます。 –

+0

多くの、多くのありがとう。私はそれが計画のように聞こえると思う。 – Paulquappe

関連する問題