<?php
/*
参考
PHP ~排他制御~
http://www.web-sky.org/program/php/php_mutex.html
*/
define("limit",15);
class mutex{
// @brief ミューテックス名
private $name;
/// @brief ロックインターバル
private $interval;
/// @brief 内部で使用するロック名
private $lock_name;
//number of trials
private $ctr=0;
function __construct($name, $interval) {
$this->name = $name;
$this->interval = $interval;
//絶対パスでないとダメ
$this->lock_name = "C:/xampp/htdocs/sample/tmp/tmp___".$name."___.lock";
}
function __destruct() {
$this->unlock();
}
public function get_ctr() {
return $this->ctr;
}
//ロックする
//limit回失敗するまでロックを試みる
public function lock() {
while (1)
{
$this->ctr+=1;
if (@mkdir ($this->lock_name, 0777))
{
break;
}
else
{
if($this->ctr==limit)
{
//limit回失敗
//ロック失敗
return true;
}
sleep ($this->interval);
}
}
//ロック成功
return false;
}
//ロックする(ロックを試みて失敗したら直ぐに戻る)
public function trylock()
{
if(is_dir($this->lock_name))
{
//ロック状態(フォルダが存在する)
//ロック失敗
return true;
}
else
{
if(@mkdir ($this->lock_name, 0777))
{
//ロック成功
return false;
}
else
{
//ロック失敗
return true;
}
}
}
//ロック解除
public function unlock()
{
if (@rmdir($this->lock_name))
{
//ロック解除成功
return false;
}
//ロック解除失敗
return true;
}
}
?>
<?php
include "mutex.php";
//排他制御
$haita=new mutex("test",2);
//ロックを1回だけ試みる
$flag_try_lock=$haita->trylock();
if($flag_try_lock)
{
//ロック失敗
//ロックをlimit回試みる
$flag_lock=$haita->lock();
$ctr=$haita->get_ctr();
echo "Number Of Trials:".$ctr."<br/>\n";
}
else
{
$flag_lock=false;
}
if($flag_lock)
{
echo "Lock Failure! Server too busy! Please try again!<br/>\n";
}
else
{
echo "Lock Success!<br/>\n";
}
//排他制御 ロック解除
if($haita->unlock())
{
echo "Unlock Failure!<br/>\n";
}
else
{
echo "Unlodk Success!<br/>\n";
}
?>
環境
OS:windows7 32bit (自作機)
xampp windows版1.74
PHP Version 5.3.5
解説
C:/xampp/htdocs/sample/mutex.php
C:/xampp/htdocs/sample/test.php
とする。
フォルダ生成でロックし、フォルダ削除でロック解除する。
PHP ~排他制御~
http://www.web-sky.org/program/php/php_mutex.html
にあったものを改造した。
今まではうまくいっていると思っていましたが読み込み途中にブラウザを閉じられた場合に unlock () されない場合が存在するようです。これは C++ にあるデストラクタがあれば問題ないと思われますが PHP にはそれが無いので回避する事は無理なようです。
と作者が言っているが、phpにデストラクタが使えるようになったので、デストラクタでunlockすると、読み込み途中でブラウザが閉じられた時や、読み込み途中にLANケーブルが引っこ抜かれたときに対応できるはず。
しかし、phpは詳しくないので本当にこれで排他制御できるか自信がありません。
コメントください。
関連
【php】destructでのrmdirでフォルダ削除失敗と対策
http://qiita.com/kyoshiro-obj/items/7203c3e710c389ea99b0
参考文献
PHP ~排他制御~
http://www.web-sky.org/program/php/php_mutex.html