fork()
を使って子プロセスを起動するperl CGIプログラムがあります。子供は長期間(約60秒)の計算を行い、最終的に結果をtmpファイルに保存します。親はブラウザーに制御を戻し、進行メッセージを表示し、子がtmpファイルを書き込んだかどうかを定期的にチェックします。ファイルが表示されたら、結果が表示されます。だから、コードは次のようになります。perlの子を待たずにフォークと返信
# Get a unique name for this job
my $guid = Data::GUID->new;
my $id = $guid->as_hex;
# Do the fork
my $pid = fork;
if (!defined $pid) {
die "cannot fork: $!";
# Child does this
} elsif ($pid == 0) {
# Do some calculations
# Save results in a filename with $id
# Parent does this
} else {
# Return the location of the tmp files to the client
return "Content-Type: text/html\n\n", $id;
# Browser uses contents of $id to check for the result file
}
私はもともとRedHatのLinux上でこれを設定し、それがうまく働きました。しかし今、私はUbuntuを実行しているサーバーに移植しようとしています。親が長時間実行している子が終了するのを待っているようです。私はこれが当てはまると信じています。なぜなら、ブラウザは計算期間中ハングし、進行状況ページを表示せず、計算が完了するとただちに結果にジャンプするからです。
これはフォークエミュレーションと関係があると思われますが、私は確信していませんし、その周りに道を見つけることができませんでした。ご意見ありがとうございます。
EDIT:このコードはサブルーチンの一部です。私はCGI :: Applicationを使用しているので、呼び出しコードはこのコードを単に使用します。したがって、return文。しかし、Red HatからLinuxに移植して以来、このコードに触れていないので、問題の原因とは考えられません。
'fork()'はPOSIXのものであり、プラットフォーム間で変更すべきではありません。私はどちらのプラットフォームもそれをエミュレートしているとは思っていません。あなたの問題はおそらく他のものです。私は、Webサーバーまたはクライアントのいずれかでバッファリングすると思います。 – Sobrique
@Sobrique:* "' fork() 'はPOSIXのことであり、プラットフォーム間で変更すべきではありません" *これは、 "プラットフォーム"という非常に限定された概念を前提としています! – Borodin
@danny:そこに 'return'があるので、これはサブルーチンの一部ですか?私はあなたが呼び出しコードを表示する必要があると思います。 ['perldoc -q 'デーモンプロセスをどのようにforkするのですか?']](https://perldoc.perl.org/perlfaq8.html#How-do-I-fork-a-daemon-プロセス%3f) – Borodin