2017-05-05 7 views
2

マルチプロセッシングプールを使用している場合、ワーカープロセスは例外がスローされたポイントを超えて実行されています。Pythonマルチプロセッシングがベース例外で終了しない

次のコードを考えてみましょう:

import multiprocessing 


def worker(x): 
    print("input: " + x) 
    y = x + "_output" 
    raise Exception("foobar") 
    print("output: " + y) 
    return(y) 


def main(): 

    data = [str(x) for x in range(4)] 
    pool = multiprocessing.Pool(1) 
    chunksize = 1 
    results = pool.map(worker, data, chunksize) 
    pool.close() 
    pool.join() 

    print("Printing results:") 
    print(results) 


if __name__ == "__main__": 
    main() 

出力は次のとおりです。

$ python multiprocessing_fail.py 
input: 0 
input: 1 
input: 2 
Traceback (most recent call last): 
input: 3 
    File "multiprocessing_fail.py", line 25, in <module> 
    main() 
    File "multiprocessing_fail.py", line 16, in main 
    results = pool.map(worker, data, 1) 
    File "/usr/lib/python2.7/multiprocessing/pool.py", line 251, in map 
    return self.map_async(func, iterable, chunksize).get() 
    File "/usr/lib/python2.7/multiprocessing/pool.py", line 558, in get 
    raise self._value 
Exception: foobar 

あなたが見ることができるように、ワーカープロセスは、第二のprint文にraise Exception("foobar")を超えて進行したことがありません。ただし、関数worker()の先頭で何度も何度も作業を再開します。

私はドキュメントの説明を探しましたが、何も見つかりませんでした。ここでは、潜在的にSO関連の質問です:

Keyboard Interrupts with python's multiprocessing Pool

しかし、それは(約キーボードがマスター・プロセスによって選ばれていない割り込み)異なっています。

別のSOの質問:ここでのマスターは例外(ライン16)をキャッチしなかったのに対し、

How to catch exceptions in workers in Multiprocessing

この質問は、マスター・プロセスは、すべての例外をキャッチdoesntのそれであるため、また異なっています。さらに重要なのは、その質問では、労働者は例外を過ぎて実行されていないことです(労働者の実行可能な行は1つだけです)。

アム走行パイソン2.7

+3

可能な複製を期待するにはどうしたいですか(http://stackoverflow.com/questions [マルチプロセッシングの労働者で例外をキャッチする方法]/22094852 /どのように例外をキャッチするのかマルチプルワーキング) – jordanm

+0

@jordanmありがとう!私はその質問を読んで、それが私のものと違うことを見出した。違いを出すために編集されました。 – akshan

+0

例外を渡して実行されているようには見えません。文字列 "output:"は決して印刷されません。それは例外がスローされ、それが死ぬと、新しい労働者を産んでいるようだ。 – jordanm

答えて

0

コメント:コードは、プールを有しているのでプールは1つのワーカーを開始すべき= multiprocessing.Pool(1)。ワーカープロセスのプールを制御プロセスプールオブジェクトは、ジョブをサブミットすることができますする


コメント:Documnentationから

:その1つのワーカーはworker()関数の複数を実行していますドキュメントから倍


map(func, iterable[, chunksize])
このメソッドは、別々のタスクなどのプロセスプールに提出するチャンクの数に反復可能にチョップ。

あなたworker()別のタスクです。 worker()の名前をtask()に変更すると、何が何であるかを明確にするのに役立ちます。

コメント:私は期待して何がそれがない例外

のワーカープロセスがクラッシュしたということです、別のタスク、あなたのworker()ダイスとPoolは、次のタスクを開始します。

terminate()
優れた作品を完了せずに、すぐにワーカープロセスを停止し :あなたが欲しい

は、ドキュメントからPool.terminate()

です。


質問:...私は、ワーカープロセスが例外がスローされたポイントを過ぎて実行し続けることがわかります。

あなたが与えるiteration dataPoolに、therfore Poolそれは何をすべきかを行います。
LEN(データ)労働者を開始します。

data = [str(x) for x in range(4)] 

主な質問です:あなたがの

raise Exception("foobar") 
+0

コードは 'pool = multiprocessing.Pool(1)'を持っているので、プールは1人のワーカーを開始する必要があります。その1人のワーカーはworker()関数を複数回実行しています(例外を複数回実行しています)。 私が期待しているのは、未処理の例外であるため、例外でワーカープロセスがクラッシュすることです。残念ながら、この文書はこの状況については何も言及していません。 – akshan

+0

コメント:コードはpool = multiprocessing.Pool(1)であるため、プールは1人のワーカーを開始する必要があります。 Documnentationから: 'ジョブを送信できるワーカープロセスのプールを制御するプロセスプールオブジェクト。'ドキュメントの次の行から : 'プロセスは と呼び出しをuse.'するワーカー・プロセスの数である: 'クラスmultiprocessing.Pool([工程〔、イニシャライザ[、initargs [maxtasksperchild ]]]]) '。 それでは、ちょうど1人の作業者を起動する必要があります。 – akshan

+0

コメント:別のタスクでworker()が死んで、Poolが次のタスクを開始します。関数worker()は関数オブジェクトであり、死ぬことはできません。プロセスが死ぬことがあります。作業者プロセス(あなたが指摘したように、worker()関数とは異なる)が死ぬことは、ここでの主な問題です。 – akshan

関連する問題