グローバル変数が "子"プロセスにどのように伝達されるかを理解するための小さなPythonプログラムを作成しました。Pythonのマルチプロセッシングモジュールと共有グローバル変数を変更する
import time
import random
shared_var = range(12)
def f(x):
global shared_var
time.sleep(1+random.random())
shared_var[x] = 100
print x, multiprocessing.current_process(), shared_var
return x*x
if __name__ == '__main__':
pool = multiprocessing.Pool(4)
results = pool.map(f, range(8))
print results
print shared_var
私はそれを実行すると、私は取得
3 <Process(PoolWorker-4, started daemon)> [0, 1, 2, 100, 4, 5, 6, 7, 8, 9, 10, 11]
0 <Process(PoolWorker-1, started daemon)> [100, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
2 <Process(PoolWorker-3, started daemon)> [0, 1, 100, 3, 4, 5, 6, 7, 8, 9, 10, 11]
1 <Process(PoolWorker-2, started daemon)> [0, 100, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
4 <Process(PoolWorker-4, started daemon)> [0, 1, 2, 100, 100, 5, 6, 7, 8, 9, 10, 11]
5 <Process(PoolWorker-1, started daemon)> [100, 1, 2, 3, 4, 100, 6, 7, 8, 9, 10, 11]
6 <Process(PoolWorker-3, started daemon)> [0, 1, 100, 3, 4, 5, 100, 7, 8, 9, 10, 11]
7 <Process(PoolWorker-2, started daemon)> [0, 100, 2, 3, 4, 5, 6, 100, 8, 9, 10, 11]
[0, 1, 4, 9, 16, 25, 36, 49]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
子プロセスは、グローバル変数を変更して以来、これは、論理的であるので、メカニズムが作るコピー・オン・ライトその子プロセスが変更されたときにそれはコピーされ、したがって、変更は生成されたプロセスでのみ表示されます。
import multiprocessing
import time
import random
shared_var = range(12)
def f(x):
global shared_var
time.sleep(1+random.random())
shared_var[x] = 100
print x, multiprocessing.current_process(), shared_var, id(shared_var)
return x*x
if __name__ == '__main__':
pool = multiprocessing.Pool(4)
results = pool.map(f, range(8))
print results
print shared_var, id(shared_var)
となった:
3 <Process(PoolWorker-4, started daemon)> [0, 1, 2, 100, 4, 5, 6, 7, 8, 9, 10, 11] 4504973968
0 <Process(PoolWorker-1, started daemon)> [100, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] 4504973968
1 <Process(PoolWorker-2, started daemon)> [0, 100, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] 4504973968
2 <Process(PoolWorker-3, started daemon)> [0, 1, 100, 3, 4, 5, 6, 7, 8, 9, 10, 11] 4504973968
6 <Process(PoolWorker-2, started daemon)> [0, 100, 2, 3, 4, 5, 100, 7, 8, 9, 10, 11] 4504973968
7 <Process(PoolWorker-3, started daemon)> [0, 1, 100, 3, 4, 5, 6, 100, 8, 9, 10, 11] 4504973968
4 <Process(PoolWorker-4, started daemon)> [0, 1, 2, 100, 100, 5, 6, 7, 8, 9, 10, 11] 4504973968
5 <Process(PoolWorker-1, started daemon)> [100, 1, 2, 3, 4, 100, 6, 7, 8, 9, 10, 11] 4504973968
[0, 1, 4, 9, 16, 25, 36, 49]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] 4504973968
(メインスレッド内と内のすべての変数の識別子、私は変数の識別子を印刷するには、コードを変更したとき
私の驚きでした生成されたプロセス)は同じですが、私は各プロセスのコピーを期待していました...
なぜ私はこれらの結果を得たのですか?また、multiprocessing
が作成したProcess
によって読み書きされているグローバル変数をどのように処理するかについての参考文献も素晴らしいでしょう。ありがとう!
変数は常に子プロセスにコピーされますか?私はそれが変更されたときにのみコピーされたと思った?カスタムクラスでも同じことが起こりますか?その場合... "コピー"メソッドが呼び出されていますか? –
ああああ、1つのコメントで非常に多くの質問:) 1.正しい2.私はフォークの内部を知らないが、結果が同じであるかどうかは、あなたがimmiediatelyをコピーするかどうか、または最初の書き込み3. Pythonは非常に無関係ですwrtカスタムと非カスタムのクラスはすべてオブジェクトです。だから私の推測です:はい。 4.私はその質問を理解していない。これはC++ではなく、コピーコンストラクタの概念はありません。 Pythonでメモリ管理に関するセパレートの質問を投稿してもよろしいでしょうか、自分よりも知識のある方がもっと情報を提供します。これはエキサイティングなトピックです! – Pavel