Cepheid [Blog]

PC全般・Web開発に関する話題や日々の生活で感じたことを中心に掲載していきます。

forkで時間のかかる処理をバックグランドで行い、ブラウザをすぐに解放させる方法。

#!/usr/local/bin/perl

# バッファリング制御
$| = 1;

# HTMLヘッダー出力
print "Content-type: text/html; charset=EUC-JP\n\n";
print "<h3>fork()のテスト</h3>\n";

FORK: {
    if( $pid = fork ) {
        # 親プロセス--------------------------------------------
        
        print "<p>親プロセスの処理</p>\n";
        
        # 標準入力/標準出力/標準エラー出力をclose
        # Apacheから終了ステータスが返りブラウザが解放される
        close(STDIN);
        close(STDOUT);
        close(STDERR);

        # 子プロセスの終了を待つ
        wait;

    } elsif (defined $pid) {
        # 子プロセス---------------------------------------------
        
        print "<p>子プロセスの処理</p>\n";

        # 標準入力/標準出力/標準エラー出力をclose
        # Apacheから終了ステータスが返りブラウザが解放される
        close(STDIN);
        close(STDOUT);
        close(STDERR);

        #####################################################
        # ▼ 時間のかかる処理(ここから)
        #####################################################
        
        sleep(10);
        
        #####################################################
        # ▲ 時間のかかる処理(ここまで)
        #####################################################
        
        exit;
        
    } elsif ( $! =~ /No more process/) {
        # プロセスが多すぎる場合、時間を置いて再開
        sleep 5;
        redo FORK;
    } else {
        # 通常ここに来ることはない
        die "Can't fork: $\n";
    }
} # End Of Label:FORK

exit;

STDIN、STDOUT、STDERRのcloseですが、UNIX環境下ではSTDOUTのcloseだけでいい様です。Windows XP&ActivePerl5.8ではSTDOUTとSTDERRの二つで解放されました。

ソースファイル

2006.09.21 17:55 | Perl | トラックバック(0) | コメント(1) |