如何触发并忘记子进程?
我有一个长时间运行的进程,我需要它来启动另一个进程(该进程也会运行很长一段时间)。 我只需要开始它,然后就完全忘记它。
我设法通过从《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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
阿尔尼塔克是对的。 这里有一个更明确的写法,没有 $$
detach 的目的只是说,“我不关心子进程何时终止”,以避免 僵尸进程。
Alnitak is right. Here's a more explicit way to write it, without $$
The purpose of detach is just to say, "I don't care when the child terminates" to avoid zombie processes.
fork
函数将您的进程一分为二。然后两个进程都会收到该函数的结果。 子进程接收到零/
nil
值(因此知道它是子进程),父进程接收子进程的 PID。因此:
将使子进程启动“某事”,而父进程将继续执行原来的操作。
请注意,
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:
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.分离
$$
是不对的。 从页。 348 镐(第二版):“Ruby 语言”一章中的“变量和常量”部分对于解码各种 ruby 短
$
常量非常方便 - 然而在线版本(第一个所以你是实际上,是将程序与其自身分离,而不是与其子程序分离。
正如其他人所说,与子进程分离的正确方法是使用从
fork()
返回的子进程的 pid。Detaching
$$
wasn't right. From p. 348 of the Pickaxe (2nd Ed):This section, "Variables and Constants" in the "Ruby Language" chapter, is very handy for decoding various ruby short
$
constants - however the online edition (the firstSo 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()
.如果您确定要分离子进程,其他答案都很好。 但是,如果您不介意,或者更愿意保留子进程(例如,您正在为 Web 应用程序启动子服务器/服务),那么您可以利用以下简写:
提供一个块告诉 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
Providing a block tells fork to execute that block (and only that block) in the child process, while continuing on in the parent.
我发现上面的答案破坏了我的终端并弄乱了输出。 这是我找到的解决方案。
以防万一有人遇到同样的问题,我的目标是登录到 ssh 服务器,然后保持该进程无限期运行。 所以 test.sh 是这样的
i found the answers above broke my terminal and messed up the output. this is the solution i found.
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