2012-05-09 44 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