7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【php】フォルダの生成と削除による排他制御

Posted at
mutex.php
<?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;
	}

}

?>

test.php

<?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

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?