読者です 読者をやめる 読者になる 読者になる

感謝のプログラミング 10000時間

たどり着いた結果(さき)は、感謝でした。

pthreadsを使って、PHPからシェルスクリプトを非同期で並列に実行するサンプル

PHP
<スポンサーリンク>

前回の記事で用意した環境が前提となる。

まずは、並列に実行したいbashを3つ用意する。
step1.shは10秒眠る。
step2.shは3秒眠る。
step3.shは5秒眠るように作る。

# cat step1.sh
--------------
#!/bin/bash

echo "my name is step1, and I sleep 10 seconds!"

sleep 10

echo "good morning! I'm step1!"
# cat step2.sh
--------------
#!/bin/bash

echo "my name is step2, and I sleep 3 seconds!"

sleep 3

echo "good morning! I'm step2!"

3は省略。

こいつらを誰の仕事が終わったとかを考えずに、並列に実行するPHPスクリプトを作ってみる。

#!/usr/bin/php

<?php
class Job extends Thread {
    public $command;

    public function __construct($command) {
        $this->command = $command;
    }

    public function run() {
       $this->invoke();
    }

    public function invoke() {
        echo $this->command;
        echo "kick this->" . $this->command,PHP_EOL;
        passthru($this->command);
    }
}

$job1 = new Job("./step1.sh");
$job2 = new Job("./step2.sh");
$job3 = new Job("./step3.sh");


$job1->start();
$job2->start();
$job3->start();

?>

コマンドの実行は、昨日の例ではshell_exec()を使ったけれど、それだと結果がコンソールに表示されないので、passthru()関数を使った。
以下を参考にすると、これ以外にも、コマンドを実行する関数はたくさんあるっぽい。
http://www.crystal-creation.com/web-appli/technical-information/programming/php/exec/

さて、これを実行してみよう。結果はこうなる。

# /usr/bin/php asyncJob.php

kick this->./step1.sh
kick this->./step2.sh
my name is step1, and I sleep 10 seconds!
kick this->./step3.sh
my name is step2, and I sleep 3 seconds!
my name is step3, and I sleep 5 seconds!
good morning! I'm step2!
good morning! I'm step3!
good morning! I'm step1!

このように、ちゃんと非同期(他の結果を待たずに)で、シェルスクリプトを並列実行することができた。

こういうのをちゃんとマルチスレッドのデザインパターンに沿ってやると、Worker Threadパターンなんかがあると思うんだけど、だいぶ前に勉強して忘れてしまったから、週末に復習したい。


このPHP HACKSがほしい。

PHP Hacks ―プロが教えるWebプログラミングテクニック

PHP Hacks ―プロが教えるWebプログラミングテクニック