【问题标题】:What are the different ways in which a process can be sent to the background?可以将进程发送到后台的不同方式有哪些?
【发布时间】:2025-12-02 04:45:01
【问题描述】:

我有一个大的 perl 脚本(大约 650 行),它可以解析 imdb.com、tvrage.com 上的数据,并且可以使用 last.fm API 和其他一些站点获取数据。该脚本使用了相当多的 Perl 模块,因此加载需要几秒钟(在旧 PC 上)。将脚本快速发送到后台有哪些不同的方式(包括任何“丑陋的黑客”)?

我将从我知道的几个开始。

  1. script.pl & 运行脚本
  2. screen -dmS script.pl 运行脚本
  3. 在脚本中使用fork()
  4. 使用App::DaemonProc::Fork

3 和 4 的问题是当脚本很大(比如 500 到 600 行)并且使用很多模块时,进程分叉并发送到后台需要一些时间。使用 #1 和 #2,它们会立即发送到后台,因此我正在寻找更多类似的解决方案。

注意:我不需要从后台进程中获取任何数据。他们正在写文件。我也不需要知道后台进程是否成功完成任务。

【问题讨论】:

  • 您希望后台进程在终端窗口关闭后仍然存在吗?
  • 并非如此。该脚本旨在由在屏幕会话中运行的另一个进程执行。

标签: perl fork


【解决方案1】:

关于 3 和 4:分叉真的不应该花很长时间,除非你在 Windows 上(模拟分叉的地方)。就我个人而言,我会选择 App::Daemon 之类的东西(或手动执行 double fork)。

另一种方法(如果它在您的平台上可用)是像 setsid script.pl 一样运行它

【讨论】:

  • 我在 Linux 上。谢谢,我从来不知道setsid,在这种情况下它似乎是最快的解决方案。我认为 fork 只需要稍微长一点的时间,因为整个脚本是 fork 的,大约 600 行,使用了 10 多个模块。
  • Proc::Daemon 是另一个很好的辅助模块——它会为你执行双叉。
【解决方案2】:

您可以通过将 Perl 模块的加载/编译推迟到 您分叉到后台之后来加速 3 和 4。

当您use 一个模块时,Perl 在“编译时”加载并编译它,这发生在脚本中的 Perl 代码执行之前,因此在您进入后台之前。如果您有很多模块,这可能需要一段时间。

您可以将use 替换为require,以便在您fork 之后在运行时 加载模块。

例如如果你有

use MyBigModule qw(run);

你可以用下面的代码替换它,放在fork的子部分:

require MyBigModule;
MyBigModule->import(qw(run));

【讨论】:

  • 感谢您的提示。我不知道 require 和 use 是不同的。我使用 require 对其进行了测试,与以前的解决方案(setsid)相比,它似乎仍然有点慢。我想当我需要一个大的分叉进程来返回数据时,我可以使用这个解决方案。
【解决方案3】:

选项 1 是即时的,因为只要您按下回车键,您就会将 pid 返回到终端,就是这样,在 bg.听起来你会知道如何使用 proc 来检查它的运行情况(如果它返回任何内容)。就您的问题而言,我会使用 opt 作为最快的。

【讨论】:

    最近更新 更多