トップページ⇒php
981コメント337KB

【Perl】ファイルロック(排他処理)について語ろう

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん02/06/23 10:18ID:eY2l+Gw1
どんな環境でも使えて、軽くて、頑丈なロックを考えようじゃありません
0002202/06/23 10:27ID:???
ずさー
0003nobodyさん02/06/23 10:38ID:???
>>1は無能。学習意欲無し

       / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄\
∧_∧  | 君さぁ こんなスレッド立てるから          |
( ´∀`)< 厨房って言われちゃうんだよ             |
( ∧∧ つ >―――――――――――――――――――‐<
 ( ゚Д゚) < おまえのことを必要としてる奴なんて         |
 /つつ  | いないんだからさっさと回線切って首吊れ     |
       \____________________/

(-_-) ハヤクシンデネ…
(∩∩)
0004nobodyさん02/06/23 10:45ID:???
いまさらねえ…
検索エンジンで調べればわらわら出てくるんですけど。
0005nobodyさん02/06/23 11:15ID:eY2l+Gw1
ワラワラでてくるのよりいいのを考えようって言ってんだよ
0006nobodyさん02/06/23 11:36ID:???
>>5
まずそのワラワラ出てくるやつを、利点、欠点と共に列挙してから始めようか
かぶると鬱だしな
0007nobodyさん02/06/23 11:39ID:eY2l+Gw1
flock(対象ファイルを直接ロック)
ファイルロック関数flockを使用して対象のファイルを直接ロックする。
特徴
・速い。
・アンロックし忘れが無い。
・ファイル毎のロックに便利。
・処理全体をロックする場合には不向き。
・flockが使えない環境もある。

flock(ロック用ファイルをロック)
ファイルロック関数flockを使用して別途用意したロック用ファイルをロックする。
特徴
・速い。
・アンロックし忘れが無い。
・処理全体をロックする場合に便利。
・ロック用ファイルが常に残る。
・サーバーによってflockが使えない場合がある。

symlink
シンボリックリンク関数symlinkを使用してロック用のシンボリックリンクを作成し、 シンボリックリンクの有無によりロック状態を判断する。
特徴
・遅い。
・ロックしたままの状態(ロック用シンボリックリンク)が残る可能性がある。
・処理全体をロックする場合に便利。
・サーバーによってsymlinkが使えない場合がある。

mkdir
ディレクトリ作成関数mkdirを使用してロック用のディレクトリを作成し、 ディレクトリの有無によりロック状態を判断する。
特徴
・遅い。
・ロックしたままの状態(ロック用ディレクトリ)が残る可能性がある。
・処理全体をロックする場合に便利。
・どの環境でも使用できる。

0008nobodyさん02/06/23 11:40ID:eY2l+Gw1
↑
http://www1.plala.or.jp/bagi/labo/lock.html
0009nobodyさん02/06/23 11:47ID:???



























0010nobodyさん02/06/23 11:48ID:???
flock(対象ファイルを直接ロック)
ファイルロック関数flockを使用して対象のファイルを直接ロックする。
特徴
・速い。
・アンロックし忘れが無い。
・ファイル毎のロックに便利。
・処理全体をロックする場合には不向き。
・flockが使えない環境もある。

flock(ロック用ファイルをロック)
ファイルロック関数flockを使用して別途用意したロック用ファイルをロックする。
特徴
・速い。
・アンロックし忘れが無い。
・処理全体をロックする場合に便利。
・ロック用ファイルが常に残る。
・サーバーによってflockが使えない場合がある。

symlink
シンボリックリンク関数symlinkを使用してロック用のシンボリックリンクを作成し、 シンボリックリンクの有無によりロック状態を判断する。
特徴
・遅い。
・ロックしたままの状態(ロック用シンボリックリンク)が残る可能性がある。
・処理全体をロックする場合に便利。
・サーバーによってsymlinkが使えない場合がある。

mkdir
ディレクトリ作成関数mkdirを使用してロック用のディレクトリを作成し、 ディレクトリの有無によりロック状態を判断する。
特徴
・遅い。
・ロックしたままの状態(ロック用ディレクトリ)が残る可能性がある。
・処理全体をロックする場合に便利。
・どの環境でも使用できる。
flock(対象ファイルを直接ロック)
ファイルロック関数flockを使用して対象のファイルを直接ロックする。
特徴
・速い。
・アンロックし忘れが無い。
0011nobodyさん02/06/23 11:48ID:???
要は複数のプロセスから共有できる資源があればいい。
0012nobodyさん02/06/23 11:48ID:???
http://tohoho.wakusei.ne.jp/lng/199903/99030145.htm
とほほ 1999/03/30(火) 00:16:25
昔、UNIXのカーネルで飯を食っていました経験から判断すると・・・
(あくまでBSD系、SystemV系UNIXでの話です。NTは知らない。)

symlink, mkdir, flockはいずれも、ロックを『かける』ことに関して
は完璧。OSがちゃんと排他制御してくれる。

「symlinkで作られたファイルが在る状態でsymlinkを使う」って言う
のを、「symlinkが衝突する」と呼ぶのであれば、この「衝突」を検出
することによってロック権を奪ったか、奪えなかったかを判断している
のであり、衝突は正常動作の範囲。

symlinkとmkdirの違いは、mkdirだと、Windowsでも利用できるという
ことくらいしかない。信頼度は同じ。

ただし、symlink, mkdirはロックを『はずす』時に問題があり、ロッ
ク中にプロセスが異常終了したりすると、ロックファイルが残ったま
まになる。

その点、flockはロックを『はずす』時も完璧で、たとえプロセスが異
常終了しても、OSがストールしても、ロックが残ることは有り得ない。
信頼性ではsymlink, mkdirよりもflockの方が高い。ただしflockは、
UNIXでもサポートしていないOSがある。

しかし、flockでも(symlink, mkdirでも)ファイルが壊れることはあ
る。これは、ロック権を持ったプロセスが中途半端に書き込んでいる最
中に異常終了するなど、ロックとは無関係の原因で発生する。

もちろん、OSやperlのバグは考えていません。バグのことを考えても、
symlink, mkdir, flockのバグの発生頻度は同じようなものでしょう。


flock使えるんなら素直に使っとけ。
0013nobodyさん02/06/23 12:31ID:???
なんで、お前らこんな単発スレにレスしてるんだ?コーディングスレあるだろ
0014nobodyさん02/06/23 12:44ID:???
>>13
そんな事言ってるあなたも
なんで単発スレにレスしてるんだ?コーディングスレあるだろ
0015nobodyさん02/06/23 13:10ID:???
>14
またまたぁ、そんなこといっちゃってー。
きみだって単発スレにレスしてるじゃん?コーディングスレあるだろ
0016nobodyさん02/06/23 13:34ID:???
>15
そんなあなたも単発スレにレスしてるんじゃないの?コーディングスレあるだろ
0017nobodyさん02/06/23 13:59ID:???
>>12
http://www.jp.qmail.org/q103/jman5/maildir.html
> NFSの実装によっては信頼できるロックをまったく持っていません。
なんてのもあるし、lockdが刺さったらしいという経験もあるんで、どうしてもflockは避けちまう。
0018nobodyさん02/06/23 15:11ID:???
>>17
そんなあなたも単発スレにレスしてるんじゃないの?コーディングスレあるだろ
0019nobodyさん02/06/23 17:37ID:eY2l+Gw1
http://tohoho.wakusei.ne.jp/soft/wlng.htm
コレのロックっていいんですか?
0020nobodyさん02/06/23 17:42ID:???
>>19
またまたぁ、そんなこといっちゃってー。
きみだって単発スレにレスしてるじゃん?コーディングスレあるだろ
0021nobodyさん02/06/23 17:44ID:???
ここが単発スレにレスしてるバカどもがいるスレですか?
0022nobodyさん02/06/23 19:15ID:???
単発質問スレもウザいが、自治厨もウザい
0023nobodyさん02/06/23 19:51ID:???
・単発質問スレ=無条件でゴミ
・単発スレ=スレが伸びればよし、伸びなければ自然消滅
区別しろよ。。。
0024 02/06/23 21:26ID:???
ロック用にファイルを1つ作っておいて、
ロック時に rename ってのはダメ?

if( rename( 元ファイル名, ロック中ファイル名 )){
  処理・・・・
}

みたいなのは
0025nobodyさん02/06/23 21:52ID:???
>>24
ありだけど、mkdirやsymlinkと変わらん
プロセス死んだときの問題もね
00262402/06/23 22:26ID:???
>>25
ありがとう。mkdirやsymlinkはよく見かけるけど、renameってのは
みないから、おれが根本的になにか勘違いしてるのかと思ってました。
0027nobodyさん02/06/23 22:49ID:???
>>24
またまたぁ、そんなこといっちゃってー。
きみだって単発スレにレスしてるじゃん?コーディングスレあるだろ
0028nobodyさん02/06/24 01:46ID:???
>>24=26
http://www.google.co.jp/search?q=rename+%E6%8E%92%E4%BB%96%E5%88%B6%E5%BE%A1&ie=UTF-8&oe=UTF8&hl=ja&lr=

ん?renameだって普通にそこらへんにあるよ?
0029nobodyさん02/06/24 03:24ID:???
>>248
またまたぁ、そんなこといっちゃってー。
きみだって単発スレにレスしてるじゃん?コーディングスレあるだろ
0030nobodyさん02/06/24 07:20ID:???
http://www.google.co.jp/search?hl=ja&ie=UTF-8&oe=UTF8&q=%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%83%AD%E3%83%83%E3%82%AF&btnG=Google+%E6%A4%9C%E7%B4%A2&lr=
0031nobodyさん02/06/24 11:29ID:???
>>30
またまたぁ、そんなこといっちゃってー。
きみだって単発スレにレスしてるじゃん?コーディングスレあるだろ
0032nobodyさん02/06/24 13:52ID:???
Perlメモのロック処理をクラスで包んでみた。
特徴
・むちゃくちゃ遅い
・アンロックし忘れがない
・処理全体をロックする場合に便利
・どの環境でも使用できる

#Lock.pm
package Lock;
use strict;
use File::Spec;

sub new{
my($class, %opt) = @_;
my %lfh = (
dir => ($opt{lockdir} || $opt{dir} || 'lock'),
file => ($opt{lockfile} || $opt{file} || 'lockfile'),
timeout => ($opt{timeout} || 60),
trytime => ($opt{trytime} || 10),
);
$lfh{path} = File::Spec->catfile($lfh{dir}, $lfh{file});
for(my $i = 0; $i < $lfh{trytime}; $i++, sleep(1))
{
return bless \%lfh => $class if(rename($lfh{path}, $lfh{current} = $lfh{path} . time));
}
local *LOCKDIR;
opendir(LOCKDIR, $lfh{dir}) or return undef;
while(my $file = readdir(LOCKDIR)){
if ($file =~ /^$lfh{file}(\d+)/){
return bless \%lfh => $class if (time - $1 > $lfh{timeout}
and rename(File::Spec->catfile($lfh{dir}, $file) => $lfh{current} = $lfh{path} . time));
last;
}
}
closedir LOCKDIR;
return undef;
}
sub DESTROY{ rename $_[0]->{current} => $_[0]->{path};}
1;
__END__
0033nobodyさん02/06/24 14:36ID:???
>>32
思うんだけど、どの環境でも使えるようにするにはrenameで統一、じゃなくて
BEGIN内で

BEGIN
{
if( find_out_if_flock_is_available() ) {
*_do_lock = \&_lock_flock;
} elsif( use_other_locking_mechanism() ) {
*_do_lock = \&_some_other_locking;
} else {
*_do_lock = \&_lock_rename;
}
}

みたいにしたらどうだろう(それじゃなきゃロックする関数内で何か
定数ををスイッチにしても同じだけど)。なんかrenameのロックとかって
イマイチ信用できんから、flock()が使えるならそれを使ったほうがよく
ない?

0034nobodyさん02/06/24 19:25ID:kznFdEhQ
flockの方が糞
0035nobodyさん02/06/24 19:27ID:???
処理全体をロックしたいばやいは

$lock = fopen('lock.txt', 'w') or exit;
flock($lock, LOCK_EX);

〜処理〜

fclose($lock);

でいいんでないかな。
0036nobodyさん02/06/24 21:15ID:???
>>35
PHPかなんかか?それ。
0037nobodyさん02/06/24 22:01ID:???
ファイルロックなんて必要なほどアクセスないからどでもいいけど、
タイムアウト処理ってどうやってる?
どの環境でも有効なタイムアウト処理となると思いつかんけどみんなは書いてる?
0038nobodyさん02/06/24 22:13ID:v5EexGcz
KENTでいいや。

flock()は途中で死ぬとタイムアウトしないみたい(永遠にロック?)なんだけど、どうするべ?
0039nobodyさん02/06/24 22:21ID:???
へ?flockはOSが後始末してくれると思ったけど
0040nobodyさん02/06/24 22:22ID:???
>>38
俺もなんか以前(×人名)そんなことあったなー。
なんでだろ?
0041nobodyさん02/06/24 22:25ID:???
まあもしflockが解放しないとしたら、シグナルハンドラでも
設定しておくしかないんじゃないの
00423802/06/24 22:29ID:???
わたしが見たソース(古い)
http://homepage1.nifty.com/glass/tom_neko/web/web_04.html

こんなことしてます。

eval {
local $SIG{ALRM} = sub { die "time out" }; # 時間が来たら抜け出す
open(OUT, "+< $datafile") or die;
alarm(5); # 先行プロセスを待つ時間(5秒)
flock(OUT, 2) or die; # ロック確認。ロック
alarm(60); # 自分自身の制限時間(1分)

一連の処理

close(OUT); # closeすれば自動でロック解除
alarm(0); # 無事済んだのでリセット
};
if ($@ =~ /time out/) {
タイムアウト時の処理
}
elsif ($@) { die }
0043j064157.ppp.asahi-net.or.jp02/06/24 22:29ID:???
Windowsってさ、flock もできなけりゃぁ、タイムアウトもできないよね。
0044nobodyさん02/06/24 22:34ID:???
ああ、これか。確かに見たことあるような。
まあ明日調べてみよう。
■ このスレッドは過去ログ倉庫に格納されています