2017-01-26 17 views
0

私はマルチプロセッシングモジュールとデコレータを学習しようとしています。Pythonマルチプロセッシング子プロセス自己終了とPickleError

from time import sleep 
from multiprocessing import Process 

class async: 
    def __init__(self, function): 
     self.func = function 
    def __call__(self, *args, **kwargs): 
     p = Process(target = self.func, args = args, kwargs = kwargs) 
     p.start() 

@async 
def printA(): 
    sleep(1) 
    print("A") 

def main(): 
    printA() 
    printA() 
    printA() 

    #do more work 

if __name__ == "__main__": 
    main() 
  1. 今私はPicklingError: Can't pickle <function printA at 0x00000273F97FF1E0>: it's not the same object as __main__.printA
    取得しています、私はこの問題を解決するかどうかはわかりません。私は以下のコードについて2つの質問があります。私はこれが私の仕事用のUNIXマシン上で動作していたように感じます、それはWindowsのものですか?

  2. 子プロセスが完了すると自己終了するようにします。私は最後にsys.exit()の関数をラップしようとしましたが、それをプロセスのターゲットとして使用しましたが、sys.exit()はゾンビプロセスを正しく終了していないようです。正しい方法は何でしょうか?

私は、ブロッキングjoin()をしたい、またdaemon=Trueを設定しないでください。最終目標は、誰かがこのモジュールをインポートし、関数に@asyncを入れ、それが別のプロセスで実行され、関数の終わりに達すると自身を終了させることです。

答えて

0
  1. 酸洗エラー:私は、問題を再現することができます。 Linuxではうまく動作しますが、Windowsではうまく動作しません。この問題は、Windowsで正しく節約できないデコレータのようです。デコレータを削除すると、この作業コードが生成されます(もちろん、これはあなたが望むものではありませんが、デザインの別のアプローチを試してください)。まったく同じ問題があるthis thread on SOもあります。

    from time import sleep 
    from multiprocessing import Process 
    
    def printA(): 
        sleep(1) 
        print("A") 
    
    def main(): 
        for i in range(3): 
         p = Process(target = printA) 
         p.start() 
    
        #do more work 
    
    if __name__ == "__main__": 
        main() 
    
  2. ゾンビがを処理:ゾンビを回避するためにあなたは親がその子供の終了コードを読んで持っている必要があります処理し、あなたはそれを行うには子プロセスに親にjoin()を実行するが必要。 、

    class async: 
        def __init__(self, function): 
         self.func = function 
         self.pool = [] 
        def __call__(self, *args, **kwargs): 
         p = Process(target = self.func, args = args, kwargs = kwargs) 
         self.pool.append(p) 
         p.start() 
        def __del__(self): 
         for p in self.pool: 
          p.join() 
    

これはPythonが@asyncのインスタンスを1つだけという効果を使用していますので、あなたはself.poolのすべてのプロセスを集めることができます:あなたはこのようなデコレータでそれを行うことができます。これは、メインプロセスの終了時にのみ実行されることに注意してください。これは、Pythonが非同期インスタンスを先に削除しないためです。

+0

1.遅延の事を申し訳ありません、私はそれを編集しました。なぜそれが機能していないのかをテストするために追加されました。それはまだありません。 2.プールオブジェクトを使用しようとしましたが、デコレータと組み合わせて使用​​しようとするとPicklingErrorsが悪化しました。 – Ben

関連する問題