2012-03-30 7 views
1

私はマルチプロセッシングを検討していました。ワーカーのためのプールで、ある状態のワーカーを初期化しようとしました。プールは呼び出し可能で初期化できますが、初期化された作業者への参照は渡されません。私が見たいくつかの例では、グローバル変数が呼び出されています。これは本当に厄介なようです。Pythonマルチプロセッシングワーカープールでの初期化の使用

マルチプロセッシングを使用してワーカーの状態を初期化する良い方法はありますか。

編集:例:

私は、私はすべての時間を行うにはしたくない(ソケットへの結合)ビット比較的高価な初期化を行うそれぞれの労働者を、持っています。手作業でソケットを初期化し、作業を割り当てたときにソケットを渡すことはできますが、プロセス間でファイル記述子を共有することは、不可能ではないにしても複雑です。だから私は初期化し、私が要求を処理するたびにバインドする必要があります。

+1

イニシャライザ関数がワーカーに参照を必要とする理由が少し不明です。多少具体的ではありますが、最小限の例を提供することができます。 – mgilson

+0

特定のファンクションコールが割り当てられる作業者を特定する方法がないことにご注意ください。それでは、単に関数の引数にその状態を含めないのはなぜですか? –

答えて

1

技術的に言えば、正しいことは、ワーカーによって実行されるすべての関数に引数として初期化関数の結果が渡されることです。

この文脈では、構築によって、異なるプロセスの別々のドメインに存在するプライベートオブジェクトが生成されるため、グローバル変数を持つことはきわめて安全です。

私の一般的な提案は、普通のreentrantプログラミングスタイルで関数を構築し、multiprocessingの機能を利用しながらグローバル変数を使用できるようにすることです。あなたの例を維持

、次send関数は、(この場合は、ソケット)いくつかのコンテキストを必要とします。

def send(socket, data): 
    pass # ... your code here 
    return dust 

労働者によって実行される初期化コードとベースのコードは、グローバル変数に依存しています便利です。

socket = None 
def init(address, port): 
    global socket 
    socket = magic(address, port) 

def job(data): 
    global socket 
    assert socket is not None 
    return send(socket, data) 

pool = multithreading.Pool(N, init, [address, port]) 
pool.map(job, ['foo', 'bar', 'baz']) 

このようにコーディングすることで、マルチプロセッシングなしでテストすることが簡単で自然になります。グローバルな状態を完全に安全なコンテキストカプセルと考えることができます。

さらに便利な点として、multiprocessingは複雑なデータ(コールバックなど)を送るのにはあまりよくありません。最良の方法は、単純なデータ(文字列、リスト、辞書、collections.namedtuple ...)を送信し、ワーカー側で(初期化関数を使用して)複雑なデータ構造を再構築することです。

関連する問題