如何在Windows上从Perl CGI脚本分离后台进程?

问题描述:

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

有没有在Windows下从CGI脚本中分离后台进程的方法?更好的是,我可以调用哪一个函数来实现跨平台的功能? (只是为了让生活更加困难,我真的很喜欢将分叉进程输出同时重定向到文件的好方法)。

如果你想这样做,独立于平台的方式,Proc::Background可能是最好的办法。

perlfork

Perl提供一个叉()关键字的 对应于 同名Unix的系统调用。在fork()系统调用 可用的大多数类似Unix的 平台上,Perl的fork()只需 就可以调用它。

在一些平台,如Windows 其中叉()系统调用不是 可用,Perl可以在解释 一级建立以 效仿叉()。虽然仿真设计 为与在 Perl程序的水平 真正的fork()的尽可能兼容的,也有从 干某些 重要区别的是,所有的伪孩子 ``过程''以这种方式创建生活在 与操作系统 相同的实际过程。

使用Win32::Process->Create与DETACHED_PROCESS参数

+0

上述网址无效。 – Rahul 2015-12-15 17:48:00

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

我使用这个效果很好,在使用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 = STL_DIR . "/aoff-caller.pl --uniqueid $uuid --region $region --ticketid $ticketid"; 
    my $daemon = Proc::Daemon->new(
    work_dir  => STL_DIR, 
    child_STDOUT => TMP_DIR . '/stdout.txt', 
    child_STDERR => TMP_DIR . '/stderr.txt', 
    pid_file  => TMP_DIR . '/' . $randnum . '-pid.txt', 
    exec_command => $callcmd, 
); 
    my $pid = $daemon->Init(); 

    exit 0; 

    (kill CGI at the appropriate place) 

我确信,产生并连接到PID随机数是矫枉过正,但我​​在创建是非常容易避免的问题没有兴趣。希望这可以帮助那些希望做同样事情的人。请记住在脚本的顶部添加use Proc::Daemon,镜像代码并更改为程序的路径和名称,您应该很好。