2

私はperlを使用してXMLでデータセットを返しています。データセットをクライアントに送信した後、クリーンアップを実行する必要がある状況に遭遇しました。しかし、mod perlとApacheのチェーンの中で、メソッドが戻るまで出力が保持される場所もあります。

のようなコマンドでバッファをクリアしようとしました。

$| =1;
STDOUT->flush(); # flush the buffer so the content is sent to the client and the finish hook can carry on, with out delaying the return.
if ($mod_perl_io){
    $mod_perl_io->rflush;
}

それでも、メソッドが戻るまで出力は得られません。次に、ブラウザが接続が閉じるのを待っていることを知り、ヘッダーにコンテンツタイプを設定するとこれが修正されるはずであることがわかりました。

rint $cgi->header(-type => "text/plain; charset=UTF-8", -cookie => $config->{'cookie'});

それでも運はありません。実際、私は常に正しいヘッダーを送信していました。

したがって、最善のオプションは、単に新しいスレッドを開始して、メソッドを返すことです。しかし、私が新しいスレッドを作成するとき。

use threads ('yield',
             'stack_size' => 64*4096,
             'exit' => 'threads_only',
             'stringify');
my $thr = threads->create('doRebuild', $dbconnect, $dbusername, $dbpassword,  $bindir);
sub doRebuild {
my ($dbconnect, $dbusername, $dbpassword,  $bindir ) = @_;
1;
}

セグメンテーション違反が発生します

[2013年2月22日金曜日10:16:47][通知]子pid26076終了信号セグメンテーション違反(11)

私が読んだことから、これはスレッドセーフな操作を確実にするためにmodperlによって行われます。これが正しいかどうかわからない。

だから私は{exe}を使ってみようと思いました

{exec   'perl', "$bindir/rebuild_needed_values.pl", qw('$dbconnect' '$dbusername' '$dbpassword');}

私が収集したものから、これはmod perlからプロセスを引き継ぎ、何も返さないようにすることです。

これはスタックオーバーフローに関する質問ほど具体的ではないことは知っていますが、この種のことは他の人がどのように解決したかという一般的な問題であるに違いありません。

4

1 に答える 1

1

fork()を使用することもできますが、バックグラウンド処理にはhttp://gearman.org/をお勧めします。

バックグラウンドプロセスがApacheのプロセスチェーンに含まれていないため、Gearmanのようなソリューションの方がはるかに優れています。

ギアマンを使用して実装した場合、プロセスはApacheの再起動後も存続します。Gearman環境はchrootjailで実行できるため、より安全です。

Gearmanを使用することの良い副作用は、バックグラウンドプロセスが他のマシンや他の言語からも呼び出せるようになることです。

Gearmanを使用すると、後でプロセスからデータを簡単に収集でき、進行状況情報をWebアプリにかなり簡単にフィードバックできます。

于 2013-02-22T13:03:39.523 に答える