PHP 5.0.4 install / fork / wait

投稿日: 2005年05月02月

PHP 5.0.4 install

pcntlモジュールを使いたかったのでついでに最新版のPHP5を落としてきてインストール。

./configure  --with-apxs2=/usr/local/apache2/bin/apxs \
             --enable-mbstring \
             --enable-zend-multibyte \
             --with-zlib \
             --enable-pcntl

fork

forkを使ったことが無いので勉強中。

PHPのpcntlモジュールは基本的にUNIXのシステムコールと同じ使い方のようなので、UNIXのシステムコールのサンプル等を見ながら。

あと、http://www.php.net/manual/ja/function.pcntl-fork.phpに投稿されているサンプルを参考に。

スタイルを変更してコメントを追記しただけでほとんど転載。

#!/usr/local/bin/php
<?php

class Process
{
    var $ident;

    function Process($ident){
        $this->ident = $ident;
    }

    function go(){
        for($i = 1; $i < 10; $i++){
            sleep(1);
            echo $this->ident . $i . "\n";
        }
    }
}

$childrenTotal = 3;
$childrenNow = 0;
$childrenNames = array( 'a', 'b', 'c' );

while($childrenNow < $childrenTotal){
    $pid = pcntl_fork();

    if($pid == -1) {
        die("error\n");
    }elseif($pid == 0){
        // 子プロセス
        $childrenNow++;
    }else{
        // 親プロセス
        $process = new Process($childrenNames[$childrenNow]);
        $process->go();
        die();
    }
}

?>

なんだけど、これって子プロセスを生成して自身はdie()して、さらにその子プロセスが子プロセスを生成して自身はdie()…ってなってるように見えるだけどそういうもの?

...
while($childrenNow < $childrenTotal){
    $pid = pcntl_fork();

    if($pid == -1) {
        die("error\n");
    }elseif($pid == 0){
        // 子プロセス
        $process = new Process($childrenNames[$childrenNow]);
        $process->go();
        die();
    }


    // 親プロセス
    $childrenNow++;
}

?>

で、いいと思うんだけど。

後、最後に子プロセスの終了を待って処理を行うようにするにはwaitすればいいのかな?

// 子プロセスの終了を待つ
pcntl_wait($status);
print("end\n");

?>

wait

さっきのwaitは子プロセス分必要だった。

// 生成した子プロセスの終了を待つ
$childrenNow = 0;

while($childrenNow < $childrenTotal){
    pcntl_wait($status, WUNTRACED);
    $childrenNow++;
}

print("end\n");

さっきのだと実行結果はこう

$ ./pcntl.php
a1
b1
c1
a2
b2
c2
...
a8
c8
b8
b9
end  <- ここで出てる
c9
a9

修正後

$ ./pcntl.php
a1
b1
c1
a2
b2
c2
...
a8
c8
b8
b9
c9
a9
end  <- ちゃんと最後に出た

無事最後にendが出た。

それから、CLI版だと出力バッファリングはないはずだけど念のため最初にob_end_flush()を入れておく。

名前:宮内 はじめ

Code for Nagoya名誉代表

E2D3名古屋支部長

プログラマーです。GISやデータビズが好きです。このサイトは宮内の個人的なメモです。

プロフィール

お問い合わせ