- ベストアンサー
forkしてもバックグラウンドで動かない
お世話になっております。 あるサイトで見たforkの例を元に下記のようなソースでバックグラウンドで処理 しようとしているんですが、処理が終わるまでブラウザがロックされて しまします。 $| = 1; rm("-f","$TmpPath$KYOTEN/result/*.*"); &Upload_Check; print "Content-type: text/html\n\n"; &DataProgHeader_Write; #画面の切替 &DataProgDetail_Write; FORK: { if( $pid = fork ) { close(STDOUT); wait; } elsif (defined $pid) { close(STDOUT); chdir "/u1/uca/htdocs/PPro"; system("perl U0302.pl $Dkyoten"); exit; } elsif ( $! =~ /No more process/) { sleep 5; redo FORK; } else { &MsgDisp("Forkできませんでした。"); } } # End Of Label:FORK バックグラウンドで動かない理由が分からないのです。 どなたかお助けください。 また、ソース中で system("perl U0302.pl $Dkyoten"); とありますが、サーバで直に動かすと正常に動作するのですが cgiから呼び出すと文字コードエラーで落ちてしまします。 (呼び出すCGIはEUCで書いていますが、U0302.PLは処理の都合上 SJISで書いています。) こちらも原因の想定がつきません。 どなたか参考サイトでも構いませんので、お教えください。 お願いいたします。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
http://www.tohoho-web.com/lng/199909/99090185.htm にあるように環境によって close(STDOUT)で開放される場合と開放されない場合があるようです。 孫プロセスを生成する方法(fork()2段で親と子を断ち切り、孫の終了はinitに任せる)なら、ゾンビを回避して親プロセスを終了できます。 が、私が使っているレンタルサーバでは、この方法でも無理でした。 取りあえずforkはあきらめた方がよいかもしれませんね。
その他の回答 (1)
- nezumi0t0k0
- ベストアンサー率70% (12/17)
forkした親プロセスがwait、つまり子プロセスの終了を待っていますよね。従って、これをCGIとして実行した場合には、子プロセスが終了し、その結果として親プロセスが終了するまでは、ブラウザはデータをロード中ということになると思います。 waitするのを止めてみると良いかもしれませんね。 ただ、その場合、例えば子プロセスが無限ループに陥った場合などに、HTTPDがそのような暴走した子プロセスを適切に殺してくれるかどうか怪しいですね。生憎私にはそのあたりのことは分かりません。
お礼
ご回答ありがとうございます。 このソースの参考になったサイトではwaitしなかった場合、ゾンビプロセスに なるので・・・と書いていたので、そのままwaitを入れたんですが これが駄目ですか・・・。 確かに、子の終了を待っている節があったので、今回の質問をさせて いただいたのですが・・・ waitを取って、子のプロセスが正常終了した場合、子プロセスがゾンビ プロセスになってしまうことはないのでしょうか? なければ、子プロセスに関しては試験で異常終了することが無いことは 確認済みなので問題ないと思うのですが、ゾンビになる可能性がある場合は 問題です。 まあ、正常終了することを確認と言っても何が起こるのわかりませんけどね・・・・ 明らかに異常終了した場合は、ゾンビになっても手動でプロセスを殺せる ので問題ないのですが正常終了の場合にゾンビになった場合は、毎回確認が 必要になるので問題です。 何らかの解決策はないでしょうか? または私のゾンビに関する知識が間違っているのでしょうか? お手数ですがわかるかたお願いいたします。
お礼
ご回答ありがとうございます。 また参考サイト、大変役に立ちました。 fork2段でもダメですか・・・ まあ、待てない時間ではないんです。処理自体は2時間くらいかかる んですけど、Forkで起動したプロセスは15分くらいで終わるので 15分なら許してくれるかも・・・ 色々と試してみます。 でも苦しいみたいですね。 ありごとうございます。