Tclスクリプトでプロセスが実行されたときに、fork()
が実行され、フォークされたプロセスが実行されたままになります。実行後にバックグラウンドで実行するように設定されていれば、例えばgvim
のように、バックグラウンドにフォークするプログラムを実行するだけで、試してみることができます:set res [exec gvim]
。プロセスがフォークして終了すると、[exec]プロセスはゾンビを去ります
メインプロセスは理論的にすぐに終了しますが、子プロセスはバックグラウンドで実行されますが、何らかの理由でメインプロセスがハングアップし、終了せず、ゾンビ状態になります(<defunct>
:ps
出力)。
私の場合、印刷を開始しているプロセスがあります。そのプロセスが終了するようにしたいと思います。問題は、私がopen "|gvim" r
を使ってプロセスを起動した場合、プロセスが終了した瞬間も認識できないということです。 fd
が[open]
によって返された場合、プログラムがゾンビになっても、[eof]
は報告されません。 [read]
を試すと、プロセスが印刷する可能性があるすべてのものを読み込むだけで、完全にハングアップします。
さらに興味深いことに、メインプロセスとフォークされたプロセスの両方で印刷されることがあり、[gets]
を使用して読み取ろうとしているときに両方が表示されることがあります。ディスクリプタをあまりに早く閉じると、パイプが壊れて[close]
が例外をスローします。おそらく、[read]
が終わることはないでしょう。
メインのプロセスが終了した瞬間を認識するための方法が必要ですが、このプロセスによって別の子プロセスが生成される可能性がありますが、この子プロセスは完全に切り離されている可能性があります。私は、メインプロセスが終了する前に印刷して、スクリプトがその作業を続行し、バックグラウンドで実行中のプロセスも実行されていて、何が起こるのか興味がないものを欲しいです。
私は始めているプロセスのソースを管理しています。はい、私はsignal(SIGCLD, SIG_IGN)
の前にfork()
の前に助けませんでした。
私は何とかあなたが合理的に答える唯一の人であることを知っていました:)。残念なことに、あなたの解決策のどれも働いていません。最初のものが 'gets'でハングアップします。スレッドの' exec'でハングアップします。これは 'gvim'でも簡単に証明できます(私は簡単にテストできるようにしました)。私は解決策が必要です:ソケット接続を受け取り、コマンドを取得し、bgでプロセスを実行し、忘れてしまいます。もう1つの要求がそれを殺すかもしれませんが、プロセスはcmdline argsによって認識されます。私はまた、プロセス自体をフォークする必要はありません、私はちょうどそれが簡単だろうと思った。 'exec ...&' 'slongsもやってもいいです。私は終了して実行し続けることができます – Ethouris
このトピックに少し興味があればいいと思います。この問題は 'bash'には存在しません。バックグラウンドにフォークして実行中のプロセスを実行すると、CLIが復帰します。 Tclで同じことをやっても、 '[exec]'コマンドは戻ってこない(終了したプロセスはゾンビのようにぶら下がっています)。それは本当にデザインによって機能しますか?通常、ゾンビは、親によってクリーンアップされるまで終了したCHILDプロセスです。しかし、どうにかして何もフォークしない同じCHILDプロセスがゾンビなしで終了します。あなたはそれを説明できますか? – Ethouris