2008-09-05 92 views
6

我在Windows上運行Perl CGI腳本時遇到了一些麻煩。主要的問題似乎是,在Windows上運行時會模擬'fork',並且實際上並沒有創建一個新進程(只是當前的另一個線程)。這意味着正在等待進程完成的Web服務器(如IIS)將繼續等待,直到「後臺」進程結束。如何在Windows上從Perl CGI腳本分離後臺進程?

有沒有在Windows下從CGI腳本中分離後臺進程的方法?更好的是,我可以調用哪一個函數來實現跨平臺的功能? (只是爲了讓生活更加困難,我真的很喜歡將分叉進程輸出同時重定向到文件的好方法)。

回答

9

如果你想這樣做,獨立於平臺的方式,Proc::Background可能是最好的辦法。

0

perlfork

Perl提供一個叉()關鍵字的 對應於 同名Unix的系統調用。在fork()系統調用 可用的大多數類似Unix的 平臺上,Perl的fork()只需 就可以調用它。

在一些平臺,如Windows 其中叉()系統調用不是 可用,Perl可以在解釋 一級建立以 效仿叉()。雖然仿真設計 爲與在 Perl程序的水平 真正的fork()的儘可能兼容的,也有從 幹某些 重要區別的是,所有的僞孩子 ``過程''以這種方式創建生活在 與操作系統 相同的實際過程。

0

我在Windows上發現了fork()的真正問題,特別是在處理Perl中的Win32對象時。因此,如果它將是Windows特定的,我真的建議你看一下Perl中的線程庫。

我使用這個效果很好,在使用IIS的網站上一次接受多個連接,然後使用更多的線程一次執行不同的腳本。

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 = STL_DIR . "/aoff-caller.pl --uniqueid $uuid --region $region --ticketid $ticketid"; 
    my $daemon = Proc::Daemon->new(
    work_dir  => STL_DIR, 
    child_STDOUT => TMP_DIR . '/stdout.txt', 
    child_STDERR => TMP_DIR . '/stderr.txt', 
    pid_file  => TMP_DIR . '/' . $randnum . '-pid.txt', 
    exec_command => $callcmd, 
); 
    my $pid = $daemon->Init(); 

    exit 0; 

    (kill CGI at the appropriate place) 

我確信,產生並連接到PID隨機數是矯枉過正,但我​​在創建是非常容易避免的問題沒有興趣。希望這可以幫助那些希望做同樣事情的人。請記住在腳本的頂部添加use Proc::Daemon,鏡像代碼並更改爲程序的路徑和名稱,您應該很好。