2016-12-12 5 views
0

自分のタスクでマルチプロセッシングを使用しようとしました。これは一般的に何らかの計算を行い、結果を戻すことを意味します。問題は、計算を定義するコードがユーザーによって定義され、実行前に文字列からコンパイルされることです。これは、メインプロセスで実行されたときにexec(),eval()またはcompile()などを使用して完璧に動作します。以下の例は、f1の機能でのみ動作しますが、f2では機能しません。私は 'クラス'コード 'を漬けません。これには何らかの方法がありますか?たとえば、マルチプロセッシングを別の方法で使用していますか?または他のパッケージを使用していますか?それとももっと低レベルのもの?プロセス全体に文字列を渡してプロセス内でコンパイルすることは、アプリケーション全体の設計(つまり、コード文字列が「失われており、コンパイルされたバージョンのみが利用可能」)のために私にとっては選択肢ではありません。は、ユーザー定義コードを多重処理できません - pickleできません

import multiprocessing 

def callf(f, a): 
    exec(f, {'a': a}) 

if __name__ == "__main__": 
    f = compile("print(a)", filename="<string>", mode="exec") 
    callf(f, 10) # this works 
    process = multiprocessing.Process(target=callf, args=(f, 20)) # this does not work 
    process.start() 
    process.join() 

更新:実際には私の実際のニーズに近い別の試みです。異なるエラーメッセージが表示されますが、その機能を実行することはできません。

import multiprocessing 

if __name__ == "__main__": 
    source = "def f(): print('done')" 
    locals = dict() 
    exec(source, {}, locals) 
    f = locals['f'] 
    f() # this works 
    process = multiprocessing.Process(target=f) # this does not work 
    process.start() 
    process.join() 
+0

コンパイル済みのオブジェクト 'f'をピクルすることはできません。つまり、実際にあなたのプロセスに渡すことはできません。一意のファイル名(つまり、ファイルとして保存)で各コードブロックを「コンパイル」して、ファイル名を各サブプロセスに渡すことができますか? –

+0

申し訳ありませんが、 'compile'のためにドキュメントを読んでいるだけで、私はものを誤読しているようです。コンパイルされたコードを簡単にファイルに保存できるかどうかは不明です。 –

答えて

0

pickleコードオブジェクトが、dill缶をシリアル化することはできません。 multiprocessing_on_dillと呼ばれるディルベースのマルチプロセッシングフォークがありますが、どれくらい良いのか分かりません。また、標準のマルチプロセッシングを幸せにするために、コードオブジェクトをディルエンコードすることもできます。

import multiprocessing 
import dill 

def callf_dilled(f_dilled, a): 
    return callf(dill.loads(f_dilled), a) 

def callf(f, a): 
    exec(f, {'a': a}) 

if __name__ == "__main__": 
    f = compile("print(a)", filename="<string>", mode="exec") 
    callf(f, 10) # this works 
    process = multiprocessing.Process(target=callf_dilled, 
     args=(dill.dumps(f), 20)) # now this works too! 
    process.start() 
    process.join() 
+1

破損した 'pickle'を置き換える' dill'、 'pathos'と関連するものを私に指摘してくれてありがとう。 'multiposcess'と呼ばれる' pathos'の部分があります。これは 'multiprocessing'のフォークです。このパッケージをインストールし、 'マルチプロセス 'を'マルチプロセス'に置き換えるだけで、私の仕事ができました。 –

関連する問題