2008-09-05 22 views
6

Windowsで実行しているときにPerl CGIスクリプトからプロセスをフォークする際に問題がありました。主な問題は、 'fork'はウィンドウ上で実行されているときにエミュレートされ、実際には新しいプロセス(現在のスレッドに別のスレッド)を作成しているようには見えないということです。つまり、プロセスの終了を待っているWebサーバー(IISなど)は、「バックグラウンド」プロセスが終了するまで待機し続けます。WindowsのPerl CGIスクリプトからバックグラウンドプロセスをフォークするにはどうすればよいですか?

WindowsのCGIスクリプトからバックグラウンドプロセスをフォークする方法はありますか?さらに、クロスプラットフォームの方法でこれを行うことができる単一の関数がありますか?

(人生をさらに難しくするために、フォークされたプロセスの出力を同時にファイルにリダイレクトするのが良い方法です)。

答えて

9

あなたは、プラットフォームに依存しない方法でこれを行いたい場合は、Proc::Backgroundは、おそらく最良の方法です。

0

perlfork

Perlが(フォークを提供する)は は同名のUnixシステムコールに対応してそのキーワード。 fork()システムコール が利用可能なほとんどのUnix風の プラットフォームでは、Perlのfork()は単に を呼び出します。フォーク()システムコールが利用可能 ないようWindowsの などのいくつかのプラットフォームで

は、Perlはインタプリタ レベルでエミュレートフォーク()を構築することができます。エミュレーションが Perlプログラムのレベルで 本当のフォーク()とできるだけ互換性があるように を設計されていますが、 から幹特定 重要な違いは、事実があることをすべての擬似子 ``プロセス''この方法で作成された のオペレーティングシステムと同じ実際のプロセスは、 です。 DETACHED_PROCESSパラメータと

0

私は、特にPerlでWin32オブジェクトを扱うときに、Windows上でfork()に関する実際の問題を発見しました。したがって、Windows固有のものになる場合は、Perl内のスレッドライブラリを参照することをお勧めします。

これは、IISを使用しているWebサイトで一度に複数の接続を受け入れてから、さらに多くのスレッドを使用して一度に異なるスクリプトを実行するのに有効です。

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を追加し、コードをミラー化してプログラムのパスと名前を変更することを忘れないでください。

関連する問題