2014年3月22日土曜日

PHP: 実行中のPHPを実行しない

クローリングシステムなど cron で定期的に PHP を実行している場合、
通信処理の遅延などが原因で予定通りの時間に終わらない場合がある。

cron で設定されたプログラムは以前のプログラムの実行が、
終わっているかどうかにかかわらず時刻通りに実行されるため、
以前の処理が終わっていない状態で次の処理が呼び出されてしまう。

前の処理が実行中に次の処理が実行されてしまうとまずい場合は、
現在同じプログラムが実行されているかどうか調べてから実行する必要がある。

PHP の最新バージョンではセマフォを使って実現できるが、
PHP 5.2 など古いバージョンの場合はセマフォの関数が準備されていない。

セマフォ - PHP
http://jp2.php.net/manual/ja/book.sem.php


そこで ps コマンドを PHP から実行して直接プロセスを検索する方法がある。
例えば、クローリングを行なう PHP ファイルが craw.php という名前であれば、
同じ名前のプログラムが実行されていないか調べることで重複起動を避けられる。
exec('ps ax | grep -e "crawl.php$" | grep -v grep', $processes, $result);
if(count($processes) > 1) {
    // 同じプロセスが既に実行されている
    exit;
}

ps ax コマンドで全てのプロセスを取得し、
grep -e "crawl.php$" で同じプログラムが実行されているか調べています。
さらに grep -v grep で、grep コマンド自体のプロセスを検索対象から排除しています。
上記のように PHP ファイル名でプロセスを検索すれば多重起動を避けられます。

参考
コマンドライン版php の簡易多重起動防止 - Softel メモ
http://www.softel.co.jp/blogs/tech/archives/2986

0 件のコメント:

コメントを投稿