2

私は "requests-futures"パッケージを使用していますが、非同期get/postコールバック(未来の結果ではadd_done_callback)で非同期get/postを呼び出しています。時々、私のコードがハングアップします。私はbashのループ内のコードのこの平和を実行する場合コールfuturがfuturコールバックになるとThreadPoolExecutorがハングします

from concurrent.futures import ThreadPoolExecutor 
import time 

pool = ThreadPoolExecutor(max_workers=10) 

def f(_): 
    time.sleep(0.1) # Try to force context switch 
    x = pool.submit(lambda: None) 
    print "1" 
    x.result() 
    print "2" 

def main(): 
    x = pool.submit(lambda : None) 
    x.add_done_callback(f) 
    print "3" 
    x.result() 
    print "4" 

print "===" 
main() 

:多くの調査時間後、私は、最小限のコードでロックを再現することができ

$> while true; do python code.py; done; 

プログラムは、「トレースですべての回をハング「:

(...) 
=== 
1 
2 
3 
4 
=== 
3 
4 
1 

私はCTRL^Cでそれを破るならば、私は次のスタックトレースがあります。

^CError in atexit._run_exitfuncs: 
Traceback (most recent call last): 
    File "/usr/lib/python2.7/atexit.py", line 24, in _run_exitfuncs 
    func(*targs, **kargs) 
    File "/home/yienyien/Angus/test/futur/env/local/lib/python2.7/site- 
packages/concurrent/futures/thread.py", line 46, in _python_exit 
    t.join(sys.maxint) 
    File "/usr/lib/python2.7/threading.py", line 951, in join 
    self.__block.wait(delay) 
    File "/usr/lib/python2.7/threading.py", line 359, in wait 
    _sleep(delay) 
KeyboardInterrupt 
Error in sys.exitfunc: 
Traceback (most recent call last): 
    File "/usr/lib/python2.7/atexit.py", line 24, in _run_exitfuncs 
    func(*targs, **kargs) 
    File "/home/yienyien/Angus/test/futur/env/local/lib/python2.7/site- 
packages/concurrent/futures/thread.py", line 46, in _python_exit 
    t.join(sys.maxint) 
File "/usr/lib/python2.7/threading.py", line 951, in join 
    self.__block.wait(delay) 
    File "/usr/lib/python2.7/threading.py", line 359, in wait 
    _sleep(delay) 
KeyboardInterrupt 
0123を

誰かが私に何が起こっているのか説明できましたか?私はthe possible deadlocksをconcurrent.futuresモジュールでチェックしますが、一致するとは思わない。

ありがとうございます。

答えて

0

固定サイズのスレッドプールに送信されたタスクは、Future.result()のようなブロック操作を呼び出すことはできません。これにより、「スレッドスターベーション」と呼ばれる特定の種類のデッドロックが発生します。また、time.sleep()を使用すると、サービスからスレッドが切り換えられ、スレッドスターベーションの確率が高くなります。

+0

私はこれが当てはまるとは思わないが、私はそれがはるかに簡単だと分かった。私は答えを書くでしょう。ありがとうございました。 –

0

私は自分の質問に答えます。 調査後、簡単です。私はTheadPoolExecutorをシャットダウンせず、withを使用しないで、main関数が完了し、メインスレッドをファイナライズすると、ThreadPoolExecutor状態はコールバックが完了しないうちに "シャットダウン"になります。

関連する問題