技術的に言えば、正しいことは、ワーカーによって実行されるすべての関数に引数として初期化関数の結果が渡されることです。
この文脈では、構築によって、異なるプロセスの別々のドメインに存在するプライベートオブジェクトが生成されるため、グローバル変数を持つことはきわめて安全です。
私の一般的な提案は、普通の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
...)を送信し、ワーカー側で(初期化関数を使用して)複雑なデータ構造を再構築することです。
イニシャライザ関数がワーカーに参照を必要とする理由が少し不明です。多少具体的ではありますが、最小限の例を提供することができます。 – mgilson
特定のファンクションコールが割り当てられる作業者を特定する方法がないことにご注意ください。それでは、単に関数の引数にその状態を含めないのはなぜですか? –