7

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

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

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

4

5 回答 5

9

如果您想以独立于平台的方式执行此操作,Proc::Background可能是最好的方式。

于 2008-09-05T13:36:59.197 回答
3

使用Win32::Process->使用 DETACHED_PROCESS 参数创建

于 2008-09-05T13:29:09.653 回答
0

perlfork

Perl 提供了一个 fork() 关键字,对应于同名的 Unix 系统调用。在大多数可以使用 fork() 系统调用的类 Unix 平台上,Perl 的 fork() 简单地调用它。

在某些平台(例如 Windows)上 fork() 系统调用不可用,可以构建 Perl 以在解释器级别模拟 fork()。虽然仿真被设计为在 Perl 程序级别尽可能地与真正的 fork() 兼容,但由于所有以这种方式创建的伪子“进程”都存在一些重要的差异。就操作系统而言,在同一个真实进程中。

于 2008-09-05T13:23:52.957 回答
0

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

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

于 2008-10-27T10:07:44.590 回答
0

这个问题很老了,接受的答案是正确的。但是,我刚刚开始工作,并想我会添加更多关于如何为需要它的人完成它的细节。

以下代码存在于一个非常大的 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在脚本顶部添加,镜像代码并更改程序的路径和名称,您应该一切顺利。

于 2018-03-11T04:04:44.210 回答