スレッド表示 | フラット表示〕 全トピック 920 件中 593 番目 次≫ ≪前

flockについて

created: 2004-06-13 10:53 | modified: 2004-06-14 06:10 | reply: 3

[1659] flockについて

user: サガ | created: 2004-06-13 10:53
こんにちは。
flock関数についてちょっと質問なんですが・・・。
あるサイトで
$fp = fopen(filename, "w");
flock($fp, 2);
fputs($fp, buffer);
flock($fp, 3);
fclose($fp);
という flock の使い方は間違っているとありました。
理由は「flock関数でロックする前に既に、ファイル内容をクリアしているから」ということでした。
しかし、PHPの書籍などを見ているとこのような使い方がされています。
この使い方は本当に間違いなのでしょうか?
reply: 1660 返信 編集 削除

[1660] flock考

user: ゆうじ | created: 2004-06-13 14:29
サガこんにちは。お久しぶりです。

flockは、ファイルそのものをロックする関数ではなく、
ファイルロックを実現する手段を提供する関数です。
ファイルそのものがロックされているわけではないということです。

なので flock($fp, 2); としていても、
別プロセスで該当するファイルの読み書きが可能です。


ある プロセスA がこの方法で書き込みを実行中に、
別の プロセスB が fopen(filename, "w") を
実行すると filename の内容は空になります。

なので例題の通りだと、タイミングによっては、
プロセスAが書き込んだ内容が反映されなかったり、
最悪、filename の内容が全て消えてしまうこともありえます。

あるサイトで言ってるのはこういうことだと思われます。


実際には、
ロック専用のファイルをロックしている間に
実ファイルの書き込みを行なう手法や、
flock関数を使わず、
テンポラリファイルやテンポラリディレクトリを作り、
それをロック中のフラグとする手法を良く見かけます。

この掲示板では後者の
ロック中に一時ディレクトリを作る方法を取っています。
掲示板やアクセスカウンタなどであればこの方法でも足ります。

// ファイルをロックする( mkdir版 )
function filelock( $fname )
{
$count = 5;
$time = 60;
for( ; $count > 0; $count--) {
if( !@mkdir( $fname.".lock", 0777 ) ) {
sleep( 1 );
}
else {
break;
}
}
if( !$count ) {
if( filemtime( $fname.".lock" ) <= time() - $time ) {
if( fileunlock( $fname ) && filelock( $fname ) ) {
return true;
}
}
return false;
}
return true;
}

// ファイルのロックを解除する
function fileunlock( $fname )
{
if( @rmdir( $fname.".lock" ) ) {
return true;
}
return false;
}


Perlですが、こちらが参考になります。

■flock考
http://www98.sakura.ne.jp/~jun/perl/flock.html
Parent: 1659  reply: 1661 1662 返信 編集 削除

[1661] なるほど

user: サガ | created: 2004-06-13 16:22
なるほど。
大変参考になりました。
ありがとうございました。
Parent: 1660  返信 編集 削除

[1662] 書き込みで再オープンすると?

user: | created: 2004-06-14 06:10
こんにちは。
私も、ファイルロックに関してはなんだか分かったような分かってないような感じでしっくりきてないクチなので、参考になります。


私は、↓こういう書き方をしたりします。

$fp = fopen(filename, "r");
flock($fp, 2);
$fp = fopen(filename, "w");
fputs($fp, buffer);
flock($fp, 3);
fclose($fp);


書き込みオープンの前にロックがかかるので、「データが飛ぶ」ことは防げているはず、と思い込んでいるんですが、どうなんでしょう?

--------------------

ただ、一つのプロセスで二つのデータを開くことがあったりするので、そういう時はゆうじさんのように別ファイルでロックするのが便利かなと思っています。
プロセスの最初(一つ目の読み書きの直前)にロックして、最後のファイル読み書きが終わった時点でロック解除、ってやると安心出来ますね。(お客さんを余計に待たせる危険性はあるのかもしれませんが)
Parent: 1660  返信 編集 削除
スレッド表示 | フラット表示〕 全トピック 920 件中 593 番目 次≫ ≪前
ページの一番上へ
Googleグックマークに登録 Yahooグックマークに登録 livedoorクリップに登録 @niftyクリップに登録 はてなブックマークに登録 deliciousに登録 Buzzurlに登録 FC2ブックマークに登録
最近更新された掲示板トピックス
管理人Blog
Yahoo Search

最近更新したNote
PHPマニュアル
今日のブックマーク
PHPマニュアル関数検索
関数名を入力し検索ボタンをクリック↑