2012-05-09 45 views
1

我有一个Perl插件需要一段时间才能完成操作。该插件通常通过网络从CGI界面启动,该界面应该在后台发送并立即打印消息。不幸的是,我找不到一种方法来做到这一点。我的意思是CGI正确启动插件,但它也等待它完成,我不想发生。我试用&,与,与detach,即使Proc::Background,至今没有运气。我很确定这个问题与CGI有关,但我想知道为什么,如果可能的话解决这个问题。以下是我尝试过的代码,请记住所有方法在控制台上都很好用,这只是CGI造成的问题。如何分离CGI中的线程?

# CGI 
my $cmd = "perl myplugin.pl"; 

# Proc::Background 
my $proc = Proc::Background->new($cmd); 
# The old friend & 
system("$cmd &"); 
# The more complicated fork 
my $pid = fork; 
if ($pid == 0) { 
    my $launch = `$cmd`; 
    exit; 
} 
# Detach 

print "Content-type: text/html\n\n"; 
print "Plugin launched!"; 

我知道有StackOverflow上一个similar question,但你可以看到它并没有解决我的问题。

+1

是什么* “至今没有运气” *是什么意思?你有错误吗?什么错误?你知道'perl myplugin.pl'是否正在执行吗?你怎么知道的? – pilcrow

+0

目前还没有运气,我的意思是它等待_myplugin.pl_完成。插件正在执行,这不是问题。 – raz3r

+0

非常基本的'$ cmd&'适合我,即CGI程序不会等待'myplugin.pl'完成。提供关于您的CGI执行环境及其配置的更多细节。请注意,您需要提供足够的信息以[重现问题](http://www.chiark.greenend.org.uk/~sgtatham/bugs.html#showmehow)。 – daxim

回答

3

让您的孩子关闭或重复其继承的标准错误和标准错误,以便Apache知道它可以自由地响应客户端。关于这个问题,请看merlyn的article

实施例:

system("$cmd >/dev/null 2>&1 &"); 

虽然我不敢看到system("$cmd ...")

+0

首先,它工作得如此之多谢谢:)第二,我可以知道你为什么认为系统很奇怪吗?我想提高我的Perl技能,所以随时解释我:D – raz3r

+2

我怀疑pilcrow认为它很奇怪。我可能会使用这个短语令人厌恶。带有一个参数的'system'调用中的变量插值会导致安全问题。使用'system'的列表形式可以防止这种情况发生,但它也会阻止shell重定向。 –

+1

@ Ven'Tatsu:Ha。 '使用警告'令人反感';' – pilcrow

4

这基本上是一个Perl执行的shell在后台执行的答案。它有两个潜在的优点,它不需要使用shell来调用你的第二个脚本,并且在叉发生故障的罕见情况下它提供了更好的用户反馈。

my @cmd = qw(perl myplugin.pl); 

my $pid = fork; 
if ($pid) { 
    print "Content-type: text/html\n\n"; 
    print "Plugin launched!"; 
} 
elsif (defined $pid) { 
    # I skip error checking here because the expectation is that there is no one to report the error to. 
    open STDIN, '<', '/dev/null'; 
    open STDOUT, '>', '/dev/null'; # or point this to a log file 
    open STDERR, '>&STDOUT'; 
    exec(@cmd); 
} 
else { 
    print "Status: 503 Service Unavailable\n"; 
    print "Content-type: text/html\n\n"; 
    print "Plugin failed to launch!"; 
} 
+1

+1不使用系统。 (我知道错误检查被省略了,但是我仍然会在exec()之后建议一个die()。) – pilcrow