Python の subprocess の preexec_fn の実装と fork のスレッドセーフティー問題

22
Ryosuke Iwanaga @riywo

Pythonのsubprocessのpreexec_fnが何やってるのか知りたい

2013-03-24 01:54:47
methane @methane

@riywo fork してから exec する前に実行して欲しい関数を指定します。具体的には os.setsid とか指定します。(最近の Python だと start_new_session キーワード引数指定できますが)

2013-03-24 02:11:06
methane @methane

@methane @riywo setsid 以外にも setuid とかいろいろ子プロセス起動時にやりたい事はあると思うので、それを関数にして渡せます。

2013-03-24 02:12:10
小崎 資広 (KOSAKI Motohiro) @kosaki55tea

@methane forkとexecの間って async signal safeな関数しか呼べないと思うのですが、pythonはどうやって解決してるのですか。興味あります

2013-03-24 02:15:08
小崎 資広 (KOSAKI Motohiro) @kosaki55tea

@methane おかげで、rubyのspawnはとんでもなく複雑なことに

2013-03-24 02:16:04
methane @methane

@kosaki55tea forkについてはロックを全部潰すとか、スレッドを現在実行してるスレッド以外潰すとかはしてますが、fork-exec間って具体的にはどういった問題があるのでしょう?

2013-03-24 02:18:36
小崎 資広 (KOSAKI Motohiro) @kosaki55tea

@methane Cのforkとexecを使うなら、かつ、マルチスレッドプログラムなら、async signal safeじゃない関数を使うとlibcの内部ロックでデッドロックしてハングする危険があります。もしかしてpythonはlibcつかってない?

2013-03-24 02:20:24
小崎 資広 (KOSAKI Motohiro) @kosaki55tea

@methane ところで、forkのときにスレッド殺すってすごい気がするんですけど、これはforkが終わったら親プロセスのほうがthread復活させないといけないですよね。そういうコンテキスト保存の仕組みを自力でつくっているということでしょうか

2013-03-24 02:24:41
methane @methane

@kosaki55tea あぁ、そういう意味ではなくて、Pythonはスレッドごとに情報持ってるんで、forkした後は死んだスレッドの情報をゴミ掃除するという意味でした>スレッド殺す

2013-03-24 02:26:30
小崎 資広 (KOSAKI Motohiro) @kosaki55tea

@methane ああ、任意のPythonコード動かせる訳じゃなくて選択肢が固定されてるのね。ならRubyとやってることは実質一緒だ

2013-03-24 02:27:18
小崎 資広 (KOSAKI Motohiro) @kosaki55tea

@methane なるほどー。Rubyのforkは死にたいやつは氏ねばー方式だなあ。Cのforkのsemanticsはずれると労多くして益すくない感がすごくて、結局シングルスレッドスクリプト専用になってますねえ > fork

2013-03-24 02:29:21
methane @methane

@kosaki55tea いや、任意の関数を渡せます. http://t.co/fGYN62HIeF なので preexec_fn 使う場合はシングルスレッドにする必要がありますね。

2013-03-24 02:29:34
小崎 資広 (KOSAKI Motohiro) @kosaki55tea

@methane あー、そういうことか。ちゃんとドキュメントに危険が書いてあるならこれでもありだなー

2013-03-24 02:30:39
methane @methane

@kosaki55tea http://t.co/WIXcP5iVIE 最近のドキュメントには Warning 書かれてますね。日本語訳だと古いので警告無かった。

2013-03-24 02:34:08
小崎 資広 (KOSAKI Motohiro) @kosaki55tea

Pythonのpopen、すごいリッチな機能もってるんだね。http://t.co/r8gQPaZgZW

2013-03-24 02:42:02
methane @methane

@kosaki55tea あれ、マルチスレッドプログラムも fork した後ってシングルスレッドですよね? まだ具体的にどういうケースでデッドロックが発生するのか想像できない。。。

2013-03-24 02:50:19
小崎 資広 (KOSAKI Motohiro) @kosaki55tea

@methane マルチスレッドだとforkのときにlibcのロック持ってるスレッドが消えてしまう事があるので、そうするとlibc lockとろうとしたときに、ロックを解法してくれる人がいないので。。。というパターンが一般的ですね。

2013-03-24 02:51:44
小崎 資広 (KOSAKI Motohiro) @kosaki55tea

@methane これは一般的にはGILでは防げなくて、なぜなら普通syscall呼ぶ直前にGIL離してしまうからです

2013-03-24 02:52:05
ふみやす@シェルまおう(自称でない) @satoh_fumiyasu

マルチスレッドで動作してたプロセスが fork したあともマルチスレッドで動いているんだとなんとなく思っていたが、どうなんだろう。マルチスレッドわからん。

2013-03-24 02:52:18
methane @methane

@kosaki55tea てことは、やっぱり fork-exec の問題と言うよりも、 fork の一般的な問題でしょうか?

2013-03-24 02:53:14
小崎 資広 (KOSAKI Motohiro) @kosaki55tea

@satoh_fumiyasu POSIXに従うならforkしたときに、fork読んだスレッド以外は複製されないので1つになります。Solarisのlib threadは別のセマンティクスをもっているのでSolarisはfork syscallが2つあります

2013-03-24 02:53:52
小崎 資広 (KOSAKI Motohiro) @kosaki55tea

@methane そうです。ああ、すいません、forkがマルチスレッドでうまく動かないのは、もうみんなに周知だろうと思ってるフシが私にはあるので

2013-03-24 02:54:53
小崎 資広 (KOSAKI Motohiro) @kosaki55tea

リア獣って褒めてるのか貶してるのかいまいち分からない

2013-03-24 02:56:52
1 ・・ 4 次へ