質問

長時間実行しているプロセスがあり、別のプロセスを起動するために必要です(しばらく実行されます)。開始するだけで、その後は完全に忘れる必要があります。

プログラミングRubyの本からいくつかのコードをすくって必要なことをやることができましたが、最善/正しい方法を見つけて、何が起こっているのかを理解したいと思います。私が最初に得たものは次のとおりです。

exec("whatever --take-very-long") if fork.nil?
Process.detach($)


それで、これが方法ですか、それとも他にどのようにすればよいですか?

以下の回答を確認した後、このコードになりました。これはより理にかなっているようです:

(pid = fork) ? Process.detach(pid) : exec("foo")


fork の仕組みについての説明をいただければ幸いです。 [すでに知っています]

$$ をデタッチしましたか?これがなぜ機能するのかわかりません。状況をよりよく把握したいのです。

役に立ちましたか?

解決

fork 関数は、プロセスを2つに分けます。

その後、

両方のプロセスが関数の結果を受け取ります。子はゼロ/ nil の値を受け取り(したがって、それが子であることを知っています)、親は子のPIDを受け取ります。

したがって:

exec("something") if fork.nil?

子プロセスは「何か」を開始し、親プロセスはそれがどこにあったかを続行します。

exec() 現在のプロセスを" something"に置き換えるので、子プロセスは以降のRubyコードを実行しないことに注意してください。

Process.detach()の呼び出しは、正しくない可能性があります。子のPIDが含まれていると予想していましたが、コードを正しく読み取った場合、実際には親プロセスが切り離されています。

他のヒント

Alnitakは正しい。以下に、$$を使用せずに明示的に記述する方法を示します

pid = Process.fork
if pid.nil? then
  # In child
  exec "whatever --take-very-long"
else
  # In parent
  Process.detach(pid)
end

デタッチの目的は、「子がいつ終了するかは気にしません」と言うことです。 ゾンビプロセスを避けるため。

デタッチ $$ は正しくありませんでした。 pから。 348本のつるはし(2nd Ed):

  

$$ Fixnum実行中のプログラムのプロセス番号。 [r / o]

このセクション、"変数と定数" " Ruby言語"章は、さまざまなルビーの短い $ 定数をデコードするのに非常に便利ですが、オンライン版(最初の

あなたが実際にやっていたのは、その子からではなく、それ自体からプログラムを切り離すことでした。 他の人が言ったように、子から切り離す適切な方法は、 fork()から返された子のpidを使用することです。

他の答えは、子プロセスをデタッチしたいことが確実な場合に適しています。ただし、気にしない場合、または子プロセスをアタッチしたままにする場合(たとえば、Webアプリのサブサーバー/サービスを起動している場合)、次の短縮形を利用できます

fork do
    exec('whatever --option-flag')
end

ブロックを提供すると、forkは子プロセスでそのブロック(およびそのブロックのみ)を実行し、親で続行します。

iは、上記の答えが私の端末を破壊し、出力を台無しにしたことを発見しました。これは私が見つけた解決策です。

   system("nohup ./test.sh &")

同じ問題が発生した場合に備えて、私の目標はsshサーバーにログインし、そのプロセスを無期限に実行し続けることでした。 test.shはこれです

#!/usr/bin/expect -f
spawn ssh host -l admin -i cloudkey  
expect "pass"
send "superpass\r"
sleep 1000000
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top