在Windows上运行时,我在使用Perl CGI脚本分析进程时遇到了一些问题。主要问题似乎是在Windows上运行时模拟“fork”,并且实际上似乎并没有创建新进程(只是当前的另一个线程)。这意味着等待进程完成的Web服务器(如IIS)将继续等待“后台”进程完成。
有没有办法从Windows下的CGI脚本中分离后台进程?更好的是,我可以调用一个以跨平台方式执行此操作的功能吗?
(只是为了让生活变得更加困难,我真的想要一个将分叉进程输出同时重定向到文件的好方法。)
答案 0 :(得分:9)
如果您想以独立于平台的方式执行此操作,Proc::Background可能是最佳方式。
答案 1 :(得分:3)
将Win32::Process->Create与DETACHED_PROCESS参数
一起使用答案 2 :(得分:0)
Perl提供了一个fork()关键字 对应于Unix系统调用 同名。在大多数类Unix上 fork()系统调用的平台 可用,Perl的fork()简单 叫它。
在某些平台上,例如Windows fork()系统调用不在哪里 可用,Perl可以构建 在解释器上模拟fork() 水平。虽然仿真是设计的 尽可能兼容 真正的fork()在级别上 Perl程序,有一定的 由此产生的重要差异 所有伪孩子的事实 以这种方式创建的``processes''存在 同样的真实过程 操作系统。
答案 3 :(得分:0)
我在Windows上发现了fork()的真正问题,特别是在Perl中处理Win32对象时。因此,如果它将特定于Windows,我建议您查看Perl中的Thread库。
我使用这个很好,在使用IIS的网站上一次接受多个连接,然后使用更多线程一次执行不同的脚本。
答案 4 :(得分: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
,镜像代码并更改程序的路径和名称,您应该好好去。