我可以有一个从浏览器启动的 Perl 脚本,派生它自己,而不是等待 child 结束吗?
Can I have a Perl script, initiated from a browser, fork itself, and not wait for the child to end?
还有 posted PerlMonks。
我的 linux 服务器上有这个非常简单的 Perl 脚本。
我希望能够从另一台机器上的浏览器调用脚本
让脚本启动一个分支
让 parent 发送一个 httpResponse(释放浏览器)
马上结束parent
让 child 完成它的工作,繁重的复杂数据库工作,这可能需要一两分钟
让 child 结束自己,没有任何输出
当我从浏览器调用此脚本时,浏览器在 child 完成之前不会收到发送的响应。
是的,从命令行调用时有效。
我想做的事可行吗?
p.s。我什至用 ProcSimple 试过了,但我还是挂断了。
#!/usr/bin/perl
local $SIG{CHLD} = "IGNORE";
use lib '/var/www/cgi-bin';
use CGI;
my $q = new CGI;
if(!defined($pid = fork())) {
die "Cannot fork a child: $!";
} elsif ($pid == 0) {
print $q->header();
print "i am the child\n";
sleep(10);
print "child is done\n";
exit;
} else {
print $q->header();
print "I am the parent\n";
print "parent is done\n";
exit 0;
}
exit 0;
一般来说,您必须 detach 父进程中的子进程才能让父进程干净地退出——否则父进程无法假定它不需要处理更多 input/output .
} elsif ($pid == 0) {
close STDIN;
close STDERR;
close STDOUT; # or redirect
do_long_running_task();
exit;
在您的示例中,子进程正在执行 print
语句,直到它退出。如果父进程已被终止并关闭其 I/O 句柄,这些打印会去哪里?
parent 进程启动另一个将自行运行的进程的一种方法是“双叉”。 child本身fork后马上退出,所以它的child被init接管了,不可能是僵尸
这可能对这里有所帮助,因为它似乎确实存在阻塞,因为文件描述符在 parent 和 child 之间共享,如评论中所述。如果 child 快速退出,这可能会起作用,但因为您需要一个长时间的 运行 作业的过程,那么 fork 两次
use warnings;
use strict;
use feature 'say';
my $pid = fork // die "Can't fork: $!";
if ($pid == 0) {
say "\tChild. Fork";
my $ch_pid = fork // die "Can't fork from child: $!";
if ($ch_pid == 0) {
# grandchild, run the long job
sleep 10;
say "\t\tgrandkid done";
exit;
}
say "\tChild, which just forked, exiting right away.";
exit;
}
say "Parent, and done";
我不确定如何模拟你的设置来测试这是否有帮助,但既然你说 child 产生“无任何输出”,它可能就足够了.它应该值得一试,因为它比 demonizing 过程(我希望能达到目的)更简单。
与@mob 的 post 类似,以下是我的网络应用程序的工作方式:
# fork long task
if (my $pid = fork) {
# parent: return with http response to web client
} else {
# child: suppress further IO to ensure termination of http connection to client
open STDOUT, '>', "/dev/null";
open STDIN, '>', "/dev/null";
open STDERR, '>', "/dev/null";
}
# Child carries on from here,
有时,(子)长进程会打印到一个信号量或状态文件,Web 客户端可能会查看该长进程何时完成。
我不记得几年前是哪个 Perl 专家建议的,但它在许多情况下都可靠地提供服务,并且从“re-visit 几年后 - 我在做什么?”中看起来非常清楚。透视...
请注意,如果 /dev/null 在 UNIX/Linux 之外不起作用,那么 @mob 对 close 的使用可能更普遍。
还有 posted PerlMonks。
我的 linux 服务器上有这个非常简单的 Perl 脚本。
我希望能够从另一台机器上的浏览器调用脚本
让脚本启动一个分支
让 parent 发送一个 httpResponse(释放浏览器)
马上结束parent
让 child 完成它的工作,繁重的复杂数据库工作,这可能需要一两分钟
让 child 结束自己,没有任何输出
当我从浏览器调用此脚本时,浏览器在 child 完成之前不会收到发送的响应。
是的,从命令行调用时有效。
我想做的事可行吗? p.s。我什至用 ProcSimple 试过了,但我还是挂断了。
#!/usr/bin/perl
local $SIG{CHLD} = "IGNORE";
use lib '/var/www/cgi-bin';
use CGI;
my $q = new CGI;
if(!defined($pid = fork())) {
die "Cannot fork a child: $!";
} elsif ($pid == 0) {
print $q->header();
print "i am the child\n";
sleep(10);
print "child is done\n";
exit;
} else {
print $q->header();
print "I am the parent\n";
print "parent is done\n";
exit 0;
}
exit 0;
一般来说,您必须 detach 父进程中的子进程才能让父进程干净地退出——否则父进程无法假定它不需要处理更多 input/output .
} elsif ($pid == 0) {
close STDIN;
close STDERR;
close STDOUT; # or redirect
do_long_running_task();
exit;
在您的示例中,子进程正在执行 print
语句,直到它退出。如果父进程已被终止并关闭其 I/O 句柄,这些打印会去哪里?
parent 进程启动另一个将自行运行的进程的一种方法是“双叉”。 child本身fork后马上退出,所以它的child被init接管了,不可能是僵尸
这可能对这里有所帮助,因为它似乎确实存在阻塞,因为文件描述符在 parent 和 child 之间共享,如评论中所述。如果 child 快速退出,这可能会起作用,但因为您需要一个长时间的 运行 作业的过程,那么 fork 两次
use warnings;
use strict;
use feature 'say';
my $pid = fork // die "Can't fork: $!";
if ($pid == 0) {
say "\tChild. Fork";
my $ch_pid = fork // die "Can't fork from child: $!";
if ($ch_pid == 0) {
# grandchild, run the long job
sleep 10;
say "\t\tgrandkid done";
exit;
}
say "\tChild, which just forked, exiting right away.";
exit;
}
say "Parent, and done";
我不确定如何模拟你的设置来测试这是否有帮助,但既然你说 child 产生“无任何输出”,它可能就足够了.它应该值得一试,因为它比 demonizing 过程(我希望能达到目的)更简单。
与@mob 的 post 类似,以下是我的网络应用程序的工作方式:
# fork long task
if (my $pid = fork) {
# parent: return with http response to web client
} else {
# child: suppress further IO to ensure termination of http connection to client
open STDOUT, '>', "/dev/null";
open STDIN, '>', "/dev/null";
open STDERR, '>', "/dev/null";
}
# Child carries on from here,
有时,(子)长进程会打印到一个信号量或状态文件,Web 客户端可能会查看该长进程何时完成。
我不记得几年前是哪个 Perl 专家建议的,但它在许多情况下都可靠地提供服务,并且从“re-visit 几年后 - 我在做什么?”中看起来非常清楚。透视...
请注意,如果 /dev/null 在 UNIX/Linux 之外不起作用,那么 @mob 对 close 的使用可能更普遍。