【问题标题】:How can I fork a background processes from a Perl CGI script on Windows?如何从 Windows 上的 Perl CGI 脚本派生后台进程?
【发布时间】:2010-09-07 22:19:07
【问题描述】:
在 Windows 上运行时,我在从 Perl CGI 脚本分叉进程时遇到了一些麻烦。主要问题似乎是在 Windows 上运行时模拟了“fork”,实际上似乎并没有创建新进程(只是当前进程中的另一个线程)。这意味着等待进程完成的 Web 服务器(如 IIS)会继续等待,直到“后台”进程完成。
有没有办法从 Windows 下的 CGI 脚本中分叉出后台进程?更好的是,我可以调用一个函数以跨平台方式执行此操作吗?
(只是为了让生活变得更加困难,我真的想要一种同时将分叉进程输出重定向到文件的好方法)。
【问题讨论】:
标签:
windows
perl
cgi
background
fork
【解决方案3】:
perlfork:
Perl 提供了一个 fork() 关键字
对应 Unix 系统调用
同名。在大多数类 Unix 上
fork() 系统调用的平台
可用,Perl 的 fork() 简单
叫它。
在某些平台上,例如 Windows
没有 fork() 系统调用的地方
可用,Perl 可以构建为
在解释器处模拟 fork()
等级。在设计仿真时
尽可能兼容
真正的 fork() 在级别
Perl 程序,有一定的
重要差异源于
事实上,所有的伪孩子
以这种方式创建的“流程”
相同的真实过程
操作系统。
【解决方案4】:
我发现在 Windows 上使用 fork() 确实存在问题,尤其是在处理 Perl 中的 Win32 对象时。因此,如果它是特定于 Windows 的,我真的建议您查看 Perl 中的 Thread 库。
我在使用 IIS 的网站上一次接受多个连接,然后使用更多线程同时执行不同的脚本,效果很好。
【解决方案5】:
这个问题很老了,接受的答案是正确的。然而,我刚刚开始工作,并想我会添加一些关于如何为需要它的人完成它的更多细节。
以下代码存在于一个非常大的 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,镜像代码并更改程序的路径和名称,您应该一切顺利。