2016-12-08 10 views
1

停止機能の実行中のステータスが「停止」されている場合、アップロード機能で例外を発生させたいと考えています。これはうまくいかないようです。私は例外を渡すためにパイプを使用しています。なにが問題ですか?あるプロセスから別のプロセスに例外を渡すには?

def upload(instances, u1): 
    for instance in instance: 
     try: 
      u1.recv() 
      #do_something 
     except: 
      #do_something_else 
      continue   

def stop(instances, s1): 
    for instance in instances: 
     RunningStatus = instance[4] 
     if RunningStatus.lower() == 'stopped'.lower(): 
      s1.send(Exception) # I want to raise exception in upload function 
           # from here 

if __name__ == '__main__': 
    s1, u1 = multiprocessing.Pipe() 
    s = multiprocessing.Process(target = stop, args = (instances, s1,)) 
    u = multiprocessing.Process(target = upload, args = (instances, u1)) 
    s.start() 
    u.start() 
    u.join() 
+1

私は学ぶためにあなたの問題を単純化しようとしますPythonで例外を処理する方法。それでも問題が解決しない場合は、問題の例をhttp://stackoverflow.com/help/mcveで最大限に作成してください。例外を「正しく」渡す方法を尋ねるだけではあまりにも曖昧です。 – PerryC

+0

@PerryCわかりやすくするために文言を変更しました。 – user6690270

+0

あなたは直接することはできません。しかし、共有された 'multiprocessing.Value'を使って、あるプロセスが他のプロセスと通信できるようにすることができます。 'Value'は、例外がいつ発生したかを示すフラグとして使用できます。追加情報が必要な場合は、それらの間にさらに情報を伝える必要があります(おそらく 'Queue'を使用します)。ドキュメントの[プロセス間の共有状態](https://docs.python.org/2/library/multiprocessing.html#sharing-state-between-processes)セクションを参照してください。 – martineau

答えて

1

ここでは、あるプロセスから別のプロセスにExceptionオブジェクトを送信する方法の例を示します。私も完全な例外情報(sys.exc_infoによって返される)を送信しようとしましたが、合理的には、これは失敗します。トレースバック情報を常に文字列にフォーマットして送信することができます(トレースバックモジュールを参照)。

Ubuntu 14.04 Python 2.7,3.4(Ubuntu提供)、および3.5(Continuum)でテスト済みです。

from __future__ import print_function 

import sys 
import multiprocessing 
import time 

def upload(u1): 
    i=0 
    try: 
     while True: 
      print('>upload>',i) 
      i+=1 
      if u1.poll(): 
       # tvt = u1.recv() 
       # raise tvt[0], tvt[1], tvt[2] # Python 2.7 
       e = u1.recv() 
       raise e 
      time.sleep(0.1) 
    except Exception as e: 
     print('Exception caught:',e) 
     print('exiting') 

def stop(s1): 
    try: 
     while True: 
      for j in range(100,110): 
       time.sleep(0.1) 
       if 105==j: 
        raise RuntimeError("oh dear at j={}".format(j)) 
    except Exception as e: 
     # tvt = sys.exc_info() 
     # s1.send(tvt) # doesn't work; tracebacks are not pickle'able 
     s1.send(e) 

if __name__ == '__main__': 
    s1, u1 = multiprocessing.Pipe() 
    s = multiprocessing.Process(target = stop, args = (s1,)) 
    u = multiprocessing.Process(target = upload, args = (u1,)) 
    s.start() 
    u.start() 
    u.join() 

出力:

>upload> 0 
>upload> 1 
>upload> 2 
>upload> 3 
>upload> 4 
>upload> 5 
>upload> 6 
Exception caught: oh dear at j=105 
exiting 
+0

'パイプ'は、この種のプロセス間通信のための良い選択のように思えます。トレースバック情報を文字列にフォーマットするには、 'io.BytesIO()'オブジェクトが 'file ='引数として提供するメモリ内のバイトバッファを 'traceback.print_exc()'で使用して、そこからデータを受け取ります送信されます。 – martineau

+0

私はWindowsで作業していましたが、これは私の要件に完全に対応しました。ありがとう。 – user6690270

0

あなたは代わりにパイプと例外の組み合わせのEventオブジェクトを使用してに見たいと思うかもしれません。イベントプリミティブを使用してプロセス間でデータを共有することで、アップロード機能がイベントを監視し、停止機能が問題を検出したときにロジックをトリガーすることができます。

私の例では、インスタンスの各インスタンスオブジェクトが配列であると仮定しているため、追加の要素でその配列を拡張すると、インスタンスごとに一意のイベントを持つことができます。

def upload(instances, u1): 
for instance in instance: 
    if instance[5].is_set(): # events only return TRUE if they are set 
     #Exception logic would go here 

    else: 
     u1.recv() 
     #do_something 


def stop(instances, s1): 
for instance in instances: 
    RunningStatus = instance[4] 
    if RunningStatus.lower() == 'stopped'.lower(): 
     instance[5].set() # Set the event to TRUE 

if __name__ == '__main__': 
    for instance in instances: 
     instance[5] = multiprocessing.Event() # create a new event semaphore 
    s = multiprocessing.Process(target = stop, args = (instances, s1,)) 
    u = multiprocessing.Process(target = upload, args = (instances, u1)) 
    s.start() 
    u.start() 
    u.join() 

マルチプロセッシングプリミティブの完全な一覧はこっち見つけることができます:https://docs.python.org/2/library/multiprocessing.html#synchronization-primitives

はここでプリミティブ他のマルチプロセッシングのオブジェクトのための様々な用途のいくつかの良い例です:https://pymotw.com/2/multiprocessing/communication.html

関連する問題