電子書籍の厳選無料作品が豊富!

■質問
CGIで内部処理を待たずにレスポンスを返す方法について教示願います。
(関連サイトを調べていて、近しいものはあったのですが、なかなか今回の問題の原因と対処に結びつく有効な手がかりがない、苦慮しています。)

■詳細
<動作環境>
 (1)画面(Java)→(2)Web(Apache)HTTPリクエスト→(3)CGI(C言語)
 (3)→(2)を介して(1)へHTTPレスポンスを送信

この環境下で、(3)の中で(3)’処理((2)へのレスポンスとは非同期で
別処理(DBへ登録する処理)言語:cshをCの中からシステムコール。
cshの中でperl処理をキックし、DB更新)を今回追加しました。

(3)’を待たずに(1)へのHTTPレスポンスを返却したいのですが、
サーバログ((1)、(2))をみると、返却のタイムスタンプを見ると、
(3)’が完了した後に返却されているようです。

方式的に(3)の中でfolkを使用し、子プロセス化することで
親は子の処理((3)’)を待たずに(2)にレスポンスを返却可能とみておりましたが、そもそもCGI(C言語)ではできないものなのでしょうか?
→C(親処理)の中にデバックを仕掛けたところ、親の終了後に子が動いているように見えています。

■ソース(概要)※詳細(原本抜粋)が必要な場合は申しつけください。
 IF文で定義
 (1)forkで子の場合、
   execlでcshを実行(cshには親でもらった引数を設定)
 (2)親の場合、
  デバックログファイルをクローズし、処理終了。

■補足(その他気になっている点)
 ・上記ソースでは、(1)の中では、親で使うログファイル出力
  のcloseを行わず、処理終了していますが、問題ないか?
 ・同(2)のとき、perlCGIでは、close(stdout);を明示しないと
  HTTPレスポンスが返却されない(子の終了を待ってしまう)
  旨、サイトの情報に記載がありましたが、C CGIでも同様に
  何かしらの明示をしないと、待たされるのか?

以上です。

A 回答 (1件)

子プロセスがレスポンスを返して、親より先に死ぬようにしたほうがよいと思います。


また、レスポンスを返さないほうのプロセスは先にSTDOUTをcloseした方が良いでしょう。

以下perlですが、やることはほぼ同じだと思います。(半角スペースを全角にしてます。)
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use CGI;
use CGI::Carp qw(fatalsToBrowser);
use CGI::Pretty;

if ( my $pid = fork ) {

  # Parent
  # Close STDOUT
  close STDOUT;

  # Do heavy work
  sleep 10;
  my $file = '/tmp/tmp3.txt';
  open my $fh, '>', $file or die "$!:$file";
  print $fh "Hello CGI. I'm parent\n";
  close $fh or die "$!:$file";

  # Wait to finish child for safe
  wait;
}
elsif ( defined $pid ) {

  # Child
  # HTTP Response
  my $q = CGI->new();
  print $q->header( -charset => 'UTF-8' );
  print $q->start_html(
    -lang => 'ja',
    -title => ' T I T L E '
  );
  print $q->p("Hello CGI. I'm child");
  print $q->end_html;
}
    • good
    • 1
この回答へのお礼

ありがとうございました。
私の開発環境ではC言語でCGIを作成しています。
Cの場合、stdoutのクローズはfclose();になりますが、当該命令を
追加することで、レスポンスを返すことができました。
★やりたいことが実現できました。ありがとうございます!

CGIでは、明示的にクローズを行うことでレスポンスを返せる事がわかりました。(まったくの初心者ですみません)
 ※因みに今まではHTTPレスポンスのBODYをSTDOUTに書き込んだ後、
  特に後続処理はなかったため、苦慮しました。
  (forkなどの使用検討も行っていました。)
以上です。

お礼日時:2010/03/15 22:22

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!