teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

追記

2018/03/09 18:18

投稿

KSwordOfHaste
KSwordOfHaste

スコア18404

answer CHANGED
@@ -33,4 +33,37 @@
33
33
 
34
34
  Windowsでspawnした場合でも実行に必要な関数群自体は新たに起動されたインタープリタへ復元されるので動くような気もしますが、「同一のインタープリタではない」のでid(obj)などオブジェクトの内部情報は元の環境とは異なると思います、spawn/forkで振る舞いに違いがでるのはそういった要因なのかも知れないと思いました。
35
35
 
36
- (ただdillが何を保証しているか何もドキュメントを読んでないので、上記は単なる推測の域を出ません)
36
+ (ただdillが何を保証しているか何もドキュメントを読んでないので、上記は単なる推測の域を出ません)
37
+
38
+ ---
39
+ 追記:書き忘れたことあるので追記しておきます
40
+
41
+ グローバル変数のスナップショットを取るのがdillの典型的な使い方だと思いますが、質問者さんがわざわざ**関数のシリアライズ**をしているのはdillがどんな動きをするか調べているということなのかなと思いました。
42
+
43
+ 子供プロセスを起動して親プロセスで定義されている関数群を用いるだけならspawnモード/forkモードにかかわらずProcessで起動した子供プロセスでそのまま親プロセスのモジュールの状態が再現された状態で動きます(※1)。つまり特殊なことをしようとしているのでない限りdillにより関数のシリアライズ/デシリアライズの必要はないと思います。
44
+
45
+ 実際、Processを用いても下記のようにfoo/bar/baz全て定義された状態で子プロセスが動きます。(質問者さんもご存知だとは思います)
46
+
47
+ ```Python
48
+ from multiprocessing import Process
49
+
50
+ def foo():
51
+ print('foo')
52
+ bar()
53
+
54
+ def bar():
55
+ print('bar')
56
+ baz()
57
+
58
+ def baz():
59
+ print('baz')
60
+
61
+ if __name__ == '__main__':
62
+ p = Process(target=foo, args=())
63
+ p.start()
64
+ print('waiting for child')
65
+ p.join()
66
+ print('child has been finished')
67
+ ```
68
+
69
+ ※1: forkシステムコールがないWindowsでは親プロセスとほぼ同一の環境で子供プロセスが開始するLinuxとは若干ことなるセマンティクスになります。Processのリファレンスにある通りです。