如何触发并忘记子进程?

发布于 2024-07-18 11:36:26 字数 548 浏览 11 评论 0原文

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

我设法通过从《Ruby 编程》一书中获取一些代码来完成我需要的操作,但我想找到最好/正确的方法,并了解发生了什么。 这是我最初得到的:

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


那么,这是这样的吗,或者我应该怎么做?

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

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


我希望能得到一些有关 fork 工作原理的解释。 [已经明白​​了]

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

I have a long running process and I need it to launch another process (that will run for a good while too). I need to only start it, and then completely forget about it.

I managed to do what I needed by scooping some code from the Programming Ruby book, but I'd like to find the best/right way, and understand what is going on. Here's what I got initially:

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

So, is this the way, or how else should I do it?

After checking the answers below I ended up with this code, which seems to make more sense:

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

I'd appreciate some explanation on how fork works. [got that already]

Was detaching $$ right? I don't know why this works, and I'd really love to have a better grasp of the situation.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

风为裳 2024-07-25 11:36:26

阿尔尼塔克是对的。 这里有一个更明确的写法,没有 $$

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

detach 的目的只是说,“我不关心子进程何时终止”,以避免 僵尸进程

Alnitak is right. Here's a more explicit way to write it, without $$

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

The purpose of detach is just to say, "I don't care when the child terminates" to avoid zombie processes.

£烟消云散 2024-07-25 11:36:26

fork 函数将您的进程一分为二。

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

因此:

exec("something") if fork.nil?

将使子进程启动“某事”,而父进程将继续执行原来的操作。

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

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

The fork function separates your process in two.

Both processes then receive the result of the function. The child receives a value of zero/nil (and hence knows that it's the child) and the parent receives the PID of the child.

Hence:

exec("something") if fork.nil?

will make the child process start "something", and the parent process will carry on with where it was.

Note that exec() replaces the current process with "something", so the child process will never execute any subsequent Ruby code.

The call to Process.detach() looks like it might be incorrect. I would have expected it to have the child's PID in it, but if I read your code right it's actually detaching the parent process.

悲凉≈ 2024-07-25 11:36:26

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

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

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

所以你是实际上,是将程序与其自身分离,而不是与其子程序分离。
正如其他人所说,与子进程分离的正确方法是使用从 fork() 返回的子进程的 pid。

Detaching $$ wasn't right. From p. 348 of the Pickaxe (2nd Ed):

$$ Fixnum The process number of the program being executed. [r/o]

This section, "Variables and Constants" in the "Ruby Language" chapter, is very handy for decoding various ruby short $ constants - however the online edition (the first

So what you were actually doing was detaching the program from itself, not from its child.
Like others have said, the proper way to detach from the child is to use the child's pid returned from fork().

我不吻晚风 2024-07-25 11:36:26

如果您确定要分离子进程,其他答案都很好。 但是,如果您不介意,或者更愿意保留子进程(例如,您正在为 Web 应用程序启动子服务器/服务),那么您可以利用以下简写:

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

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

The other answers are good if you're sure you want to detach the child process. However, if you either don't mind, or would prefer to keep the child process attached (e.g. you are launching sub-servers/services for a web app), then you can take advantage of the following shorthand

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

Providing a block tells fork to execute that block (and only that block) in the child process, while continuing on in the parent.

七分※倦醒 2024-07-25 11:36:26

我发现上面的答案破坏了我的终端并弄乱了输出。 这是我找到的解决方案。

   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

i found the answers above broke my terminal and messed up the output. this is the solution i found.

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

just in case anyone has the same issue, my goal was to log into a ssh server and then keep that process running indefinitely. so test.sh is this

#!/usr/bin/expect -f
spawn ssh host -l admin -i cloudkey  
expect "pass"
send "superpass\r"
sleep 1000000
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文