代码之家  ›  专栏  ›  技术社区  ›  Matt Sheppard

如何从Windows上的PerlCGI脚本派生后台进程?

  •  6
  • Matt Sheppard  · 技术社区  · 16 年前

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

    有没有一种方法可以从Windows下的CGI脚本中派生出一个后台进程?更好的是,是否有一个我可以调用的函数可以以跨平台的方式实现这一点?

    (为了让生活变得更加困难,我真的希望有一个好方法可以同时将分叉的进程输出重定向到一个文件)。

    5 回复  |  直到 6 年前
        1
  •  9
  •   Leon Timmermans    16 年前

    如果你想以一种平台独立的方式来做这件事, Proc::Background 可能是最好的方法。

        2
  •  3
  •   aku    16 年前

    使用 Win32::Process->Create 带分离的过程参数

        3
  •  0
  •   Espo    16 年前

    perlfork :

    Perl提供了一个fork()关键字, 对应的Unix系统调用 同名。在大多数类Unix上 fork()系统调用的平台 是可用的,Perl的fork()只是 叫它。

    在某些平台上,如Windows 其中fork()系统调用不是 可用,Perl可以构建为 在解释器上模拟fork()。 水平。在设计仿真时 尽可能与 真正的fork()在 Perl程序,有 重要的差异源于 事实上所有的假孩子 ``以这种方式创建的进程在 就同一个真实的过程 涉及操作系统。

        4
  •  0
  •   Spedge    16 年前

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

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

        5
  •  0
  •   Jeffrey Tackett    6 年前

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

    以下代码存在于一个非常大的PerlCGI脚本中。这个特殊的子程序在多个票务系统中创建票,然后使用返回的票号通过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 在脚本的顶部,镜像代码并更改程序的路径和名称,这样做应该很好。