22

我有一个长时间运行的进程,我需要它来启动另一个进程(也将运行一段时间)。我只需要启动它,然后完全忘记它。

我设法通过从 Programming Ruby 书中获取一些代码来做我需要的事情,但我想找到最好/正确的方法,并了解正在发生的事情。这是我最初得到的:

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


那么,这是这样的方式,还是我应该怎么做?

检查下面的答案后,我最终得到了这段代码,这似乎更有意义:

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


我会很感激一些关于如何fork工作的解释。[已经知道了]

分离$$对吗?我不知道为什么会这样,我真的很想更好地了解情况。

4

5 回答 5

32

阿尔尼塔克是对的。这是一种更明确的编写方式,没有 $$

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

分离的目的只是说,“我不在乎孩子何时终止”以避免僵尸进程

于 2009-04-30T10:35:12.183 回答
22

fork功能将您的流程分成两部分。

然后两个进程都会收到函数的结果。孩子收到零值/ nil(因此知道它是孩子),父母收到孩子的PID。

因此:

exec("something") if fork.nil?

将使子进程开始“某事”,而父进程将继续进行。

请注意,将当前进程exec() 替换为“某物”,因此子进程将永远不会执行任何后续 Ruby 代码。

调用Process.detach()看起来可能不正确。我本来希望它里面有孩子的PID,但是如果我正确地阅读了你的代码,它实际上是在分离父进程。

于 2009-04-30T10:19:36.433 回答
2

分离$$是不对的。从 p。348 镐(第 2 版):

$$Fixnum 正在执行的程序的进程号。[转/转]

“Ruby 语言”一章中的“变量和常量”这一部分,对于解码各种 ruby​​ 短常量非常方便$- 但是在线版(第

所以你实际上在做的是将程序与自身分离,而不是与它的子程序分离。就像其他人所说的那样,与孩子分离的正确方法是使用从fork().

于 2009-04-30T12:37:53.730 回答
2

如果您确定要分离子进程,其他答案很好。但是,如果您不介意,或者希望保持子进程的连接(例如,您正在为 Web 应用程序启动子服务器/服务),那么您可以利用以下速记

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

提供一个块告诉 fork 在子进程中执行该块(并且只执行该块),同时在父进程中继续执行。

于 2013-07-13T20:36:02.730 回答
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
于 2016-06-29T18:46:37.363 回答