[PHP-users 10953] Re: Flockについて
Yoshi
php-users@php.gr.jp
Sat, 19 Oct 2002 01:34:26 -0700
すみません。
$modeを書きわすれました。
$modeは"w"をつかってます。
これはもんだいなんでしょうか?
wlockout()の方は実際の書き込みには関係ないので
説明しませんでした。すみませんでした。
wlockout()はあまりに消えるので、困り果てたあげくに
制作した自作のFunctionで、基本的には操作中の(書き込み中の)
ファイル名を「操作中ファイル」として別のDrictoryに書き込み、
別の書き込み命令が操作中のファイルに来たときに、
そのファイルが操作中の場合操作を待機するためのものです。
一応下につけておきますが、基本的には関係ないと思います。
//実際は下のfile_write()を書き込みに使ってます。
//書き込みの時にflockの補助としてwlockin ()を一応適応してます。(下を参照)
function file_write( $FileName , $DATA , $mode ){
if( $lockid = wlockin ( $FileName ) ){ //ファイルロック(自作)
if($fp = @fopen ( $FileName , "$mode")){
if(flock( $fp , LOCK_EX )){ //flock
fputs ($fp , $DATA );
fflush ( $fp );
flock ( $fp , LOCK_UN ); //flock
fclose ($fp);
}
}
wlockout( $lockid );//ファイルロック開放(自作)
return 1;
}
}
<?
/*
//使用例
$PATH_TO_LOCK_FILE = "./lockdir"; //ロックファイルを書きこむデイレクトリー
$LockTarget = "log file"; //ロックをかけたいログファイル名
$lockid = wlockin ( $LockTarget );//ファイルのロック
wlockout( $lockid );//ロック開放
*/
// wlockin ( $LOCK_DIR_PATH , $LockTarget )
//ファイルをロックする関数。Lockに成功した場合Lock IDを返します。
//==========================================================================
======================
function wlockin ( $LockTarget ){
$PATH_TO_LOCK_ROOT_LAYER = "/home/wlock_root"; //ここでPathを指定
$timestamp = time(); //Get timestamp for lock file
$NewLockID = md5 ( uniqid (rand())); // Make uniq id for lock file
exec ( "echo $LockTarget > $PATH_TO_LOCK_ROOT_LAYER/$NewLockID" );
//Traget filename をいれたLock fileを制作
touch ( "$PATH_TO_LOCK_ROOT_LAYER/$NewLockID" , $timestamp );//Lock file
のタイムスタンプを合わせる
while( !$lockid = _wlockin( "$PATH_TO_LOCK_ROOT_LAYER" , $NewLockID ,
$timestamp , $LockTarget ) ){ //ファイルLock
srand((double)microtime()*1000000);
$rand = rand( 0 , 1000 );
usleep( $rand );
if( !file_exists ("$PATH_TO_LOCK_ROOT_LAYER/$NewLockID" ) ){
return 0;
}
}
return $lockid;
}
//==========================================================================
======================
// _wlockin ( $PATH_TO_LOCK_ROOT_LAYER , $NewLockID , $NewFileTime ,
$LockTarget )
//ファイルロックを実際に行う関数。先に作られたファイルをチェックする。
//==========================================================================
======================
function _wlockin ( $PATH_TO_LOCK_ROOT_LAYER , $NewLockID , $NewFileTime ,
$LockTarget ){
$handle = opendir($PATH_TO_LOCK_ROOT_LAYER);
$OrderArray[0] = $NewLockID;
while ( $LockedFile = readdir( $handle ) ) {
if( "." != trim($LockedFile) && ".." != trim($LockedFile) ) { //[.][..]
を排除
$LockedFileTime = filemtime ( "$PATH_TO_LOCK_ROOT_LAYER/$LockedFile" );
//Get file time
if( $LockedFileTime <= $NewFileTime ){ //NewLockIDと同じかより前のFile
があれば比較
if( trim( exec("cat $PATH_TO_LOCK_ROOT_LAYER/$LockedFile") ) ==
$LockTarget ) {
if( $LockedFileTime == $NewFileTime ){
$OrderArray[1] = $LockedFile;
sort ($OrderArray); //FileTimeが同じ場合sortして一つ返す
return $rtn = ( $NewLockID == $OrderArray[0] ) ? $NewLockID : 0;
}else{
return 0; //NewLockIDより小さいFileTimeあれば偽を返す
}
}
}
}
}
closedir($handle);
return $NewLockID;
}
//==========================================================================
======================
//wlockout( $PATH_TO_LOCK_ROOT_LAYER , $lockid )
//ファイルロックを開放する関数
//==========================================================================
======================
function wlockout( $lockid ){
$PATH_TO_LOCK_ROOT_LAYER = "/home/wlock_root"; //ここでPathを指定
unlink ( "$PATH_TO_LOCK_ROOT_LAYER/$lockid");
}
//==========================================================================
======================
//wlock_clean( $PATH_TO_LOCK_ROOT_LAYER , 30 )
//ゴーストロックファイル消去関数(クローンから呼び出し)
//==========================================================================
======================
function wlock_clean( $LockTimeLimit){
$PATH_TO_LOCK_ROOT_LAYER = "/home/wlock_root"; //ここでPathを指定
$handle = opendir($PATH_TO_LOCK_ROOT_LAYER);
$timestamp = time();
while ( $LockFile = readdir( $handle ) ) {
if( "." != trim($LockFile) && ".." != trim($LockFile) ) { //[.][..]を排
除
$LockFileTime = filemtime ( "$PATH_TO_LOCK_ROOT_LAYER/$LockFile" );
//Get file time
if( $LockFileTime <= $timestamp - $LockTimeLimit ){ //$LockTimeLimit秒
前のファイルは全て消去
unlink ( "$PATH_TO_LOCK_ROOT_LAYER/$LockFile");
}
}
}
closedir($handle);
}
//==========================================================================
======================
?>
----- Original Message -----
From: "WADA Masashi" <wada@hh.iij4u.or.jp>
To: <php-users@php.gr.jp>
Sent: Friday, October 18, 2002 8:28 PM
Subject: [PHP-users 10950] Re: Flockについて
>
> 和田です。
>
> 私も以前 flock() について、本 ML に質問させてもらったことがあ
> ります。
>
> Yoshi wrote:
> >問題のファイル参照時はこんな感じのFUNCTIONを使ってます。
> >あと、wlockinはあまりに消えるんで、自分でもう一つファイルを
> >作ってLOCKをする関数を作って適応してます。
> >(これは実際の書き込みはしないので、気にしないで下さい)
>
> 肝心のwlockin()とwlockout()の中身が紹介されていないので、根本
> 的な原因は推測しかできませんけど・・・。
>
> > if($fp = @fopen ( $FileName , "$mode")){
> >
> > if(flock( $fp , LOCK_EX )){ //flock
>
> $mode には何を指定していますか? "w"だったりすると、まずいこ
> とが起きる可能性があります。
>
> [PHP-jp 10324] flockの不具合?
>
> から始まるスレッドを参照してください。
>
> まずは、ファイルロックが競合する状況を起こりやすくさせるテスト
> スクリプトを書いて、確実な検証を行っておいた方がいいですね。
>
>
> ----
> 和田雅志 (WADA Masashi)
> wada@hh.iij4u.or.jp
> _______________________________________________
> PHP-users mailing list
> PHP-users@php.gr.jp
> http://ns1.php.gr.jp/mailman/listinfo/php-users