我有一个漫长的运行过程,我需要它来启动另一个进程(也将运行一段时间)。我只需要启动它,然后完全忘掉它。
我设法通过从编程Ruby书中搜索一些代码来完成我所需要的工作,但我想找到最佳/正确的方法,并了解正在发生的事情。这是我最初得到的:
exec("whatever --take-very-long") if fork.nil?
Process.detach($$)
那么,这是方式,还是我应该怎么办?
检查下面的答案后,我最终得到了这段代码,这似乎更有意义:
(pid = fork) ? Process.detach(pid) : exec("foo")
我很感激fork
如何运作的一些解释。 [已经得到了]
正在分离$$
吗?我不知道为什么会这样,我真的很想更好地掌握这种情况。
答案 0 :(得分:31)
Alnitak是对的。这是一种更明确的编写方式,没有$$
pid = Process.fork
if pid.nil? then
# In child
exec "whatever --take-very-long"
else
# In parent
Process.detach(pid)
end
分离的目的只是说,“我不关心孩子什么时候终止”以避免zombie processes。
答案 1 :(得分:20)
fork
功能将您的流程分为两部分。
两个进程都会收到函数的结果。孩子收到的值为零/ nil
(因此知道它是孩子),父母收到孩子的PID。
因此:
exec("something") if fork.nil?
将使子进程启动“某事”,并且父进程将继续进行。
请注意exec()
用“something”替换当前进程,因此子进程永远不会执行任何后续的Ruby代码。
对Process.detach()
的调用看起来可能不正确。我原以为它会让孩子的PID在其中,但是如果我正确读取你的代码,它实际上是在分离父进程。
答案 2 :(得分:2)
脱离$$
是不对的。从p。 Pickaxe(第二版)中的348个:
$$
Fixnum正在执行的程序的进程号。 [r / o]
“Ruby语言”一章中的“变量和常量”这个部分对于解码各种ruby短$
常量非常方便 - 但是在线版本(第一个
所以你实际上在做的是将程序与自己分开,而不是从它的孩子那里分离出来。
像其他人所说的那样,与孩子分离的正确方法是使用从fork()
返回的孩子的pid。
答案 3 :(得分:2)
如果您确定要分离子进程,其他答案都很好。但是,如果您不介意,或者更愿意保留子进程(例如,您正在为Web应用程序启动子服务器/服务),那么您可以利用以下简写
fork do
exec('whatever --option-flag')
end
提供一个块告诉fork在子进程中执行该块(并且只有那个块),同时在父进程中继续。
答案 4 :(得分:0)
我发现上面的答案打破了我的终端并弄乱了输出。这是我找到的解决方案。
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