在 Windows 上运行时,我在从 Perl CGI 脚本分叉进程时遇到了一些问题。主要问题似乎是在 Windows 上运行时模拟“fork”,并且实际上似乎并没有创建新进程(只是当前进程中的另一个线程)。这意味着等待进程完成的 Web 服务器(如 IIS)将继续等待,直到“后台”进程完成。

有没有办法在 Windows 下从 CGI 脚本中分出后台进程?更好的是,是否有一个我可以调用的函数可以跨平台方式执行此操作?

(只是为了让生活变得更加困难,我真的很想要一种将分叉进程输出同时重定向到文件的好方法)。

有帮助吗?

解决方案

如果您想以独立于平台的方式执行此操作, 过程::背景 也许是最好的方法。

其他提示

使用 Win32::进程->创建 使用 DETACHED_PROCESS 参数

佩尔福克:

Perl提供了与同名UNIX系统调用相对应的叉()关键字。在大多数类似于Unix的平台上,可以使用fork()系统调用,Perl's Fork()只是调用它。

在某些平台(例如fork()系统调用的Windows)上,可以在解释器级别构建Perl以模仿叉()。虽然仿真的设计与PERL程序级别的真实叉()尽可能兼容就操作系统而言,在相同的实际过程中。

我发现 Windows 上的 fork() 确实存在问题,尤其是在 Perl 中处理 Win32 对象时。因此,如果它是 Windows 特定的,我真的建议您查看 Perl 中的 Thread 库。

我使用此方法可以很好地在使用 IIS 的网站上一次接受多个连接,然后使用更多线程同时执行不同的脚本。

这个问题很老了,接受的答案是正确的。然而,我刚刚让它发挥作用,并想我应该为任何需要它的人添加一些关于如何完成它的更多细节。

以下代码存在于一个非常大的 Perl CGI 脚本中。此特定子例程在多个票务系统中创建票证,然后使用返回的票证号码通过 Twilio 服务进行自动呼叫。该调用需要一段时间,我不希望 CGI 用户必须等到调用结束才能看到其请求的输出。为此,我做了以下工作:

  (All the CGI code that is standard stuff.  Calls the subroutine needed, and then)

  my $randnum = int(rand(100000));
  my $callcmd = $progdir_path . "/aoff-caller.pl --uniqueid $uuid --region $region --ticketid $ticketid";
  my $daemon = Proc::Daemon->new(
    work_dir     => $progdir_path,
    child_STDOUT => $tmpdir_path . '/stdout.txt',
    child_STDERR => $tmpdir_path . '/stderr.txt',
    pid_file     => $tmpdir_path . '/' . $randnum . '-pid.txt',
    exec_command => $callcmd,
  );
  my $pid = $daemon->Init();

  exit 0;

  (kill CGI at the appropriate place)

我确信生成并附加到 pid 的随机数是多余的,但我没有兴趣创建非常容易避免的问题。希望这可以帮助那些想要做同样事情的人。记得添加 use Proc::Daemon 在脚本的顶部,镜像代码并更改程序的路径和名称,然后就可以开始了。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top