2017-11-30 1 views
0

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に移植して以来、このコードに触れていないので、問題の原因とは考えられません。

+0

'fork()'はPOSIXのものであり、プラットフォーム間で変更すべきではありません。私はどちらのプラットフォームもそれをエミュレートしているとは思っていません。あなたの問題はおそらく他のものです。私は、Webサーバーまたはクライアントのいずれかでバッファリングすると思います。 – Sobrique

+0

@Sobrique:* "' fork() 'はPOSIXのことであり、プラットフォーム間で変更すべきではありません" *これは、 "プラットフォーム"という非常に限定された概念を前提としています! – Borodin

+0

@danny:そこに 'return'があるので、これはサブルーチンの一部ですか?私はあなたが呼び出しコードを表示する必要があると思います。 ['perldoc -q 'デーモンプロセスをどのようにforkするのですか?']](https://perldoc.perl.org/perlfaq8.html#How-do-I-fork-a-daemon-プロセス%3f) – Borodin

答えて

1

ランダルシュワルツのWatching long processes through CGIが有用な例を提供する。これは、フォークに簡単です:

if (my $pid = fork) {  # parent does 

    delete_all();    # clear parameters 
    param('session', $session); 
    print redirect(self_url()); 
} 
elsif (defined $pid) { # child does 

    close STDOUT;   # so parent can go on 

    unless (open F, "-|") { 

     open STDERR, ">&=1"; 
     exec "/usr/sbin/traceroute", $host; 
     die "Cannot execute traceroute: $!"; 
    } 

記事の残りの部分は、実行中のジョブを追跡し、ユーザーを支援する方法を説明します。

関連する問題