PHP 5.0.4 install / fork / wait
投稿日: 2005年05月02日 更新日: 2017年07月22日
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やデータビズが好きです。このサイトは宮内の個人的なメモです。