【Perl】ファイルロック(排他処理)について語ろう
レス数が950を超えています。1000を超えると書き込みができなくなります。
0001nobodyさん
02/06/23 10:18ID:eY2l+Gw100022
02/06/23 10:27ID:???0003nobodyさん
02/06/23 10:38ID:???/ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄\
∧_∧ | 君さぁ こんなスレッド立てるから |
( ´∀`)< 厨房って言われちゃうんだよ |
( ∧∧ つ >―――――――――――――――――――‐<
( ゚Д゚) < おまえのことを必要としてる奴なんて |
/つつ | いないんだからさっさと回線切って首吊れ |
\____________________/
(-_-) ハヤクシンデネ…
(∩∩)
0004nobodyさん
02/06/23 10:45ID:???検索エンジンで調べればわらわら出てくるんですけど。
0005nobodyさん
02/06/23 11:15ID:eY2l+Gw10007nobodyさん
02/06/23 11:39ID:eY2l+Gw1ファイルロック関数flockを使用して対象のファイルを直接ロックする。
特徴
・速い。
・アンロックし忘れが無い。
・ファイル毎のロックに便利。
・処理全体をロックする場合には不向き。
・flockが使えない環境もある。
flock(ロック用ファイルをロック)
ファイルロック関数flockを使用して別途用意したロック用ファイルをロックする。
特徴
・速い。
・アンロックし忘れが無い。
・処理全体をロックする場合に便利。
・ロック用ファイルが常に残る。
・サーバーによってflockが使えない場合がある。
symlink
シンボリックリンク関数symlinkを使用してロック用のシンボリックリンクを作成し、 シンボリックリンクの有無によりロック状態を判断する。
特徴
・遅い。
・ロックしたままの状態(ロック用シンボリックリンク)が残る可能性がある。
・処理全体をロックする場合に便利。
・サーバーによってsymlinkが使えない場合がある。
mkdir
ディレクトリ作成関数mkdirを使用してロック用のディレクトリを作成し、 ディレクトリの有無によりロック状態を判断する。
特徴
・遅い。
・ロックしたままの状態(ロック用ディレクトリ)が残る可能性がある。
・処理全体をロックする場合に便利。
・どの環境でも使用できる。
0008nobodyさん
02/06/23 11:40ID:eY2l+Gw1http://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が使えない場合がある。
symlink
シンボリックリンク関数symlinkを使用してロック用のシンボリックリンクを作成し、 シンボリックリンクの有無によりロック状態を判断する。
特徴
・遅い。
・ロックしたままの状態(ロック用シンボリックリンク)が残る可能性がある。
・処理全体をロックする場合に便利。
・サーバーによってsymlinkが使えない場合がある。
mkdir
ディレクトリ作成関数mkdirを使用してロック用のディレクトリを作成し、 ディレクトリの有無によりロック状態を判断する。
特徴
・遅い。
・ロックしたままの状態(ロック用ディレクトリ)が残る可能性がある。
・処理全体をロックする場合に便利。
・どの環境でも使用できる。
flock(対象ファイルを直接ロック)
ファイルロック関数flockを使用して対象のファイルを直接ロックする。
特徴
・速い。
・アンロックし忘れが無い。
0011nobodyさん
02/06/23 11:48ID:???0012nobodyさん
02/06/23 11:48ID:???とほほ 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:???0015nobodyさん
02/06/23 13:10ID:???またまたぁ、そんなこといっちゃってー。
きみだって単発スレにレスしてるじゃん?コーディングスレあるだろ
0016nobodyさん
02/06/23 13:34ID:???そんなあなたも単発スレにレスしてるんじゃないの?コーディングスレあるだろ
0017nobodyさん
02/06/23 13:59ID:???http://www.jp.qmail.org/q103/jman5/maildir.html
> NFSの実装によっては信頼できるロックをまったく持っていません。
なんてのもあるし、lockdが刺さったらしいという経験もあるんで、どうしてもflockは避けちまう。
0019nobodyさん
02/06/23 17:37ID:eY2l+Gw1コレのロックっていいんですか?
0021nobodyさん
02/06/23 17:44ID:???0022nobodyさん
02/06/23 19:15ID:???0023nobodyさん
02/06/23 19:51ID:???・単発スレ=スレが伸びればよし、伸びなければ自然消滅
区別しろよ。。。
ロック時に rename ってのはダメ?
if( rename( 元ファイル名, ロック中ファイル名 )){
処理・・・・
}
みたいなのは
002624
02/06/23 22:26ID:???ありがとう。mkdirやsymlinkはよく見かけるけど、renameってのは
みないから、おれが根本的になにか勘違いしてるのかと思ってました。
0028nobodyさん
02/06/24 01:46ID:???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だって普通にそこらへんにあるよ?
0030nobodyさん
02/06/24 07:20ID:???0032nobodyさん
02/06/24 13:52ID:???特徴
・むちゃくちゃ遅い
・アンロックし忘れがない
・処理全体をロックする場合に便利
・どの環境でも使用できる
#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:???思うんだけど、どの環境でも使えるようにするには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:kznFdEhQ0035nobodyさん
02/06/24 19:27ID:???$lock = fopen('lock.txt', 'w') or exit;
flock($lock, LOCK_EX);
〜処理〜
fclose($lock);
でいいんでないかな。
0037nobodyさん
02/06/24 22:01ID:???タイムアウト処理ってどうやってる?
どの環境でも有効なタイムアウト処理となると思いつかんけどみんなは書いてる?
0038nobodyさん
02/06/24 22:13ID:v5EexGczflock()は途中で死ぬとタイムアウトしないみたい(永遠にロック?)なんだけど、どうするべ?
0039nobodyさん
02/06/24 22:21ID:???0041nobodyさん
02/06/24 22:25ID:???設定しておくしかないんじゃないの
004238
02/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.jp
02/06/24 22:29ID:???0044nobodyさん
02/06/24 22:34ID:???まあ明日調べてみよう。
0046nobodyさん
02/06/25 13:13ID:???「古いロックファイル(ディレクトリ)の削除」の項で、作成時間が10分以上
前であることを確認したあとにリネームするのって複数プロセスでかち合う典型
だろ? このサイトの人ってそこんとこ理解しないで画期的とか書いてるYO!
http://homepage1.nifty.com/glass/tom_neko/web/web_04.html#deletelock
if ((-M $lockdir) * 86400 > 600) { # 作成時間が10分以上前なら
rename($lockdir2, $lockdir); # ロック入れ替え
last; # 一連の処理へ
}
0047nobodyさん
02/06/25 13:45ID:???0049nobodyさん
02/06/25 15:02ID:???プロセスが変な状態で生きてる時ぐらいじゃないのかな。
プロセスが完全に死んだら解放されると思うけど。
ま、暴走ってなんだって言われても困るが。
0050nobodyさん
02/06/25 16:28ID:+Rl2IvER0051fusianasan
02/06/25 16:36ID:???ファイル追加書き込みを10000ループぐらい連続でやるスクリプトを
同時に複数プロセスから実行させて、書き込まれた行数で判断すれば?
0052nobodyさん
02/06/25 17:04ID:???0053nobodyさん
02/06/25 18:20ID:???0054nobodyさん
02/06/25 18:21ID:???0055nobodyさん
02/06/25 21:07ID:???0056nobodyさん
02/06/25 21:15ID:???/ ヽ\
/ ヽ \ / \
/ ヽ \__ / ヽ \
/ ‐_ ヽ ―――__/ ヽ \
/  ̄ / __ ヽ \
|  ̄ \
| |
| || |
| ゝ_ |||/ |
| ( ・ ブ ゝ__ ┃ ┃ |
|  ̄ ( ・ ̄ ̄ ブ ┛ ┗ |
| ゝ__ ノ ━┓ ┏ | ┃ ┃
| __  ̄ ┃ | ┃ ┃
| | ̄ ̄ーヽ | ┃ ┃
| | ヽ |
| | |ヽ | ━┓
\ _⊥_ | | ┃┛
\  ̄ ̄ヽ_⊥ | ┏━┓
\ | ┏┛
\ / ・
0057nobodyさん
02/06/25 22:30ID:???0058nobodyさん
02/06/26 06:14ID:???0059nobodyさん
02/06/26 11:58ID:???/ ヽ\
/ ヽ \ / \
/ ヽ \__ / ヽ \
/ ‐_ ヽ ―――__/ ヽ \
/  ̄ / __ ヽ \
|  ̄ \
| |
| || |
| ゝ_ |||/ |
| ( ・ ブ ゝ__ ┃ ┃ |
|  ̄ ( ・ ̄ ̄ ブ ┛ ┗ |
| ゝ__ ノ ━┓ ┏ | ┃ ┃
| __  ̄ ┃ | ┃ ┃
| | ̄ ̄ーヽ | ┃ ┃
| | ヽ |
| | |ヽ | ━┓
\ _⊥_ | | ┃┛
\  ̄ ̄ヽ_⊥ | ┏━┓
\ | ┏┛
\ / ・
0060「このサイトの人」
02/06/26 17:34ID:uIGx/rWA>作成時間が10分以上
>前であることを確認したあとにリネームするのって複数プロセスでかち合う典型
>だろ?
コードをちゃんと読んでもらえれば分かりますが、ロックファイルを消すときの
排他のために、もうひとつ違うロックファイルを作ってます。ということで冗談
のような方法なので「画期的」とふざけてみたわけで。第2のロックファイルが
残っても消せないのが欠点。
残ったロックファイルを消す方法で、いまのところ完璧だと思うのは、
http://www.din.or.jp/~ohzaki/perl.htm#File_Lock
のrename式じゃないかな。
0061nobodyさん
02/06/26 17:45ID:???__,,:::=========:::,,_,__
...‐''゙ . ` ,_ ` ''‐...
..‐´ ゙ `‐..
─┼─ /\ / ○ \
─┼─ /\/_.........;;;;;;;;;;;;;;;;::´ (⌒,) .l ヽ.:;;;;;;;;;;;;;;;;;;;;;;................. |||
│ / ゙゙ .'  ̄ ヽ __ , ─| ヽ ゙゙゙゙゙゙゙゙゙゙゙゙゙;;;;;;;;;;......。・ ・ ・
| / / ヽ .| ゙: ゙゙゙゙゙;;;;;;
゙゙゙゙゙;;;;;;;;............ ;゙ ヽ l ゙; .............;;;;;;;;゙゙゙゙゙
゙゙゙゙゙゙゙゙゙;;;;;;;;;;;;;;;;;.......;............................. .ヽ ./ ..................................;.......;;;;;;;;;;;;;;;;;゙゙゙゙゙゙゙゙゙ ____
::::日F|xxx・,`:::::::::::::::::: ゙゙゙゙タ.゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ヽ ./゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙!!゙゙゙゙゙ ::::::::::::::::::`'*[] H]. |[][]|:
::::日日II[][]'l*:::::::::::::::::: ノキli; i . .;, 、 .,, .V ` ; 、 .; ´ ;,i!!|iγ :::::::::::::::::::j;‘日/ .|[][]|::::
::::口旦 E=Д;‘`::::::::::::::::::::: /゙||lii|li||,;,.il|i;, ; . ., ,li ' ; .` .; il,.;;.:||i .i| :;il|!!|;(゙ ::::::::::::::::::::::"‘、Дロ::::
::::Д日T† ;j;::::::::::::::::::::::: `;;i|l|li||lll|||il;i:ii,..,.i||l´i,,.;,.. .il `, ,i|;.,l;;:`ii||iil||il||il||l||i|lii゙ゝ :::::::::::::::::::::::・;日日T::: 日::::
::::Hvv´+"::::::::::::::::::::::::: ゙゙´`´゙-;il||||il|||li||i||iiii;ilii;lili;||i;;;,,|i;,:,i|liil||ill|||ilill|||ii||lli゙/`゙ :::::::::::::::::::::::::´.'田#v[][]†~~†::::
::::v[]>:・':::::::::::::::::::::::::: ゙`゙⌒ゞ;iill|||lli|llii:;゙|lii|||||l||ilil||i|llii;|;_゙ι´゚゙´`゙ ::::::::::::::::::::::::::+`:F|ロxxx::::
::::田#YYv、*;::::::::::::::::::::::::::::::::::::::: ´゙゙´`゙``´゙`゙´``´゙`゙゙´´ ::::::::::::::::::::::::::::::::::::::::,,・、::日旦::::
::::ロ|=|E」vxxx:`l::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::;:`+E| ∩v |=|::::
0063fusianasan
02/06/26 19:33ID:???全然わかってないねー。まだ気づかないの?
0064「このサイトの人」
02/06/26 19:46ID:uIGx/rWAどの程度可能性があるのか分かりませんが、システムコール等が滞って、
プロセスが終了しなくなった状況を想定してみました。単に混んで遅く
なってる時に強制終了したらまずいですね。制限時間が1分は短かいかも。
要は、ロックファイルが残った時のように特別な場合です。そういう
方法もあるって事で紹介しましたが、実用性はあまり無いかもしれません。
0065「このサイトの人」
02/06/26 19:57ID:uIGx/rWAたしかに、わたしが全然分かってないのかもしれませんが。
下記のどこに問題がありますか?
$retry = 5; # リトライ回数セット
while (!mkdir($lockdir, 0755)) { # 作成。出来なければ待つ
if (--$retry <= 0) { # 5回ダメなら
if (mkdir($lockdir2, 0755)) { # ロックを消すための排他
if ((-M $lockdir) * 86400 > 600) { # 作成時間が10分以上前なら
rename($lockdir2, $lockdir); # ロック入れ替え
last; # 一連の処理へ
}
else { rmdir($lockdir2); } # 部分ロック削除
}
&error("BUSY"); # あきらめる
}
sleep(1); # 1秒待つ
}
1.作成時間が10分以上前なら
この隙間には他のプロセスが入れないよう2つ目のロックファイルで排他してある。
2.ロック入れ替え
0066fusianasan
02/06/26 20:08ID:???リネームに成功したかどうか、結果を確認できていない。
もしAというプロセスが10分以上前と判断した状態でプロセスを次に渡して、
Bというプロセスがリネームまで成功してCというプロセスが$lockdir2を作って
しまったら、Aというプロセスもリネームできてしまいロックできないのでは?
0067「このサイトの人」
02/06/26 22:17ID:uIGx/rWAなるほど。rename失敗までは考えていませんでした。
となると、プロセスAが$lockdir2を作り、かつrename失敗すると、
古い$lockdirと $lockdir2と両方が残りますね。デッドロックには
なりますが、次のプロセスは入って来れないんじゃないでしょうか?
「$lockdir2を消す」「$lockdirの作成時間を変える」をrenameで
いっぺんに行ってますが、$lockdir2 が消え$lockdirが更新されな
い、というrename失敗はあり得ますか?
あるいは、rename失敗時にはアトミックではなくなるとか?
0068fusianasan
02/06/26 22:39ID:???わかった?
プロセスA:作成時間が10分以上前と判断して処理を次へ渡す
プロセスB:作成時間が10分以上前と判断してリネームまで成功
プロセスC:$lockdir2を作成後、作成時間が10分以上前ではないからはじかれる
プロセスA:$lockdir2が存在するからリネーム成功
0069fusianasan
02/06/26 22:47ID:???勿論、作成時間が10分以上前ではない場合に削除する処理になってはいるが
これもまた削除する前に処理を次へ渡してしまう可能性もあることを念の為に。
0070nobodyさん
02/06/26 22:59ID:???/ ヽ\
/ ヽ \ / \
/ ヽ \__ / ヽ \
/ ‐_ ヽ ―――__/ ヽ \
/  ̄ / __ ヽ \
|  ̄ \
| |
| || |
| ゝ_ |||/ |
| ( ・ ブ ゝ__ ┃ ┃ |
|  ̄ ( ・ ̄ ̄ ブ ┛ ┗ |
| ゝ__ ノ ━┓ ┏ | ┃ ┃
| __  ̄ ┃ | ┃ ┃
| | ̄ ̄ーヽ | ┃ ┃
| | ヽ |
| | |ヽ | ━┓
\ _⊥_ | | ┃┛
\  ̄ ̄ヽ_⊥ | ┏━┓
\ | ┏┛
\ / ・
0071「このサイトの人」
02/06/26 23:51ID:uIGx/rWAあれ?
>プロセスA:作成時間が10分以上前と判断して処理を次へ渡す
と
>プロセスA:$lockdir2が存在するからリネーム成功
の間には他のプロセスは割り込めませんよ。
リネームを試みる前には$lockdir2がプロセスB等他を弾きます。
プロセスAがリネームを試みるのは一度だけ。
●作成時間が10分以上前の場合
プロセスA:ロックディレクトリ1に阻まれる(排他される)
プロセスA:ロックディレクトリ2を作成(排他)
プロセスA:作成時間が10分以上前と判断
プロセスA:$lockdir2が存在するからリネーム(ロックディレクトリ2をロックディレクトリ1に変換)(排他終了)
→プロセスBが割り込めるとしたらここだけ。しかもリネームが失敗した場合。
プロセスA:そのままロックに守られ排他が必要な処理
プロセスA:ロックディレクトリ1を消す
で、$lockdir2 が消え$lockdirが更新されない、というrename失敗
(こんなのあるの?)の場合だけプロセスBが割り込めます。
●作成時間が10分以上前ではない場合
プロセスA:ロックディレクトリ1に阻まれる(排他される)
プロセスA:ロックディレクトリ2を作成(排他)
プロセスA:作成時間が10分以上前でないと判断
プロセスA:ロックディレクトリ2を削除(排他終了)
プロセスA:&error("BUSY")でプロセス終了
0072nobodyさん
02/06/27 12:25ID:???/ ヽ\
/ ヽ \ / \
/ ヽ \__ / ヽ \
/ ‐_ ヽ ―――__/ ヽ \
/  ̄ / __ ヽ \
|  ̄ \
| |
| || |
| ゝ_ |||/ |
| ( ・ ブ ゝ__ ┃ ┃ |
|  ̄ ( ・ ̄ ̄ ブ ┛ ┗ |
| ゝ__ ノ ━┓ ┏ | ┃ ┃
| __  ̄ ┃ | ┃ ┃
| | ̄ ̄ーヽ | ┃ ┃
| | ヽ |
| | |ヽ | ━┓
\ _⊥_ | | ┃┛
\  ̄ ̄ヽ_⊥ | ┏━┓
\ | ┏┛
\ / ・
0073nobodyさん
02/06/27 12:36ID:???/ ヽ\
/ ヽ \ / \
/ ヽ \__ / ヽ \
/ ‐_ ヽ ―――__/ ヽ \
/  ̄ / __ ヽ \
|  ̄ \
| |
| || |
| ゝ_ |||/ |
| ( ・ ブ ゝ__ ┃ ┃ |
|  ̄ ( ・ ̄ ̄ ブ ┛ ┗ |
| ゝ__ ノ ━┓ ┏ | ┃ ┃
| __  ̄ ┃ | ┃ ┃
| | ̄ ̄ーヽ | ┃ ┃
| | ヽ |
| | |ヽ | ━┓
\ _⊥_ | | ┃┛
\  ̄ ̄ヽ_⊥ | ┏━┓
\ | ┏┛
0074nobodyさん
02/06/27 14:32ID:???/ ヽ\
/ ヽ \ / \
/ ヽ \__ / ヽ \
/ ‐_ ヽ ―――__/ ヽ \
/  ̄ / __ ヽ \
|  ̄ \
| |
| || |
| ゝ_ |||/ |
| ( ・ ブ ゝ__ ┃ ┃ |
|  ̄ ( ・ ̄ ̄ ブ ┛ ┗ |
| ゝ__ ノ ━┓ ┏ | ┃ ┃
| __  ̄ ┃ | ┃ ┃
| | ̄ ̄ーヽ | ┃ ┃
| | ヽ |
| | |ヽ | ━┓
\ _⊥_ | | ┃┛
\  ̄ ̄ヽ_⊥ | ┏━┓
\ | ┏┛
\ / ・
0075nobodyさん
02/06/27 17:02ID:???0076nobodyさん
02/06/27 17:20ID:???/ ヽ\
/ ヽ \ / \
/ ヽ \__ / ヽ \
/ ‐_ ヽ ―――__/ ヽ \
/  ̄ / __ ヽ \
|  ̄ \
| |
| || |
| ゝ_ |||/ |
| ( ・ ブ ゝ__ ┃ ┃ |
|  ̄ ( ・ ̄ ̄ ブ ┛ ┗ |
| ゝ__ ノ ━┓ ┏ | ┃ ┃
| __  ̄ ┃ | ┃ ┃
| | ̄ ̄ーヽ | ┃ ┃
| | ヽ |
| | |ヽ | ━┓
\ _⊥_ | | ┃┛
\  ̄ ̄ヽ_⊥ | ┏━┓
\ | ┏┛
\ / ・
0077nobodyさん
02/06/27 20:25ID:???\∧_ヘ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
,,、,、,,, / \〇ノゝ∩ < 1000取り合戦、いくぞゴルァ!! ,,、,、,,,
/三√ ゚Д゚) / \____________ ,,、,、,,,
/三/| ゚U゚|\ ,,、,、,,, ,,、,、,,,
,,、,、,,, U (:::::::::::) ,,、,、,,, \オーーーーーーーッ!!/
//三/|三|\ ∧_∧∧_∧ ∧_∧∧_∧∧_∧∧_∧
∪ ∪ ( ) ( ) ( ) )
,,、,、,,, ,,、,、,,, ∧_∧∧_∧∧_∧ ∧_∧∧_∧∧_∧∧_∧
,,、,、,,, ( ) ( ) ( ) ( )
0078「このサイトの人」
02/06/28 01:42ID:lpc8XUFVとりあえず結論出しておきます。
rename失敗の殆どの場合、何も起こらなかった、つまり古いロック
1とロック2 が両方残ることになるでしょうから、その時には他のプ
ロセスが侵入することはありません。
万一、ロック2が消え古いロック1が残ると排他は失敗しますが、そ
の場合、ロック2のディレクトリが消失したか、違う名前にrenameさ
れたことになりますね。ファイルシステムのエラーによって、絶対
起こらない事とは言えませんが、そこまで考慮する必要があるのか
どうかは疑問。
疑問ではありますが、あえて考慮するなら、上記のわたしの排他制
御で、
rename($lockdir2, $lockdir) or &error("LOCK ERROR");
として、rename失敗したプロセスを、その時点で終了させることに
すれば問題なくなります。
ごく稀にロック2が残る可能性は残りますが、ロック1が残る可能性
より低いのですから、残存ロック削除機能付きの排他方法として、
それなりに使えるのではないかと。
では。
0080nobodyさん
02/06/29 07:01ID:???∧∧
|\ <ヽ`∀´> /|
ヾ  ̄ ̄ ̄ ̄ ̄  ̄ ̄ ̄ ̄ ̄ ̄ ̄ /
 ̄ ̄ ̄ ̄ ̄ ̄| | ̄ ̄ ̄ ̄ ̄ ̄ ̄
| |
/ ̄ ̄ ̄ ̄\/ ̄ ̄ ̄ ̄ ̄\
__/ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄\ .\__ ドドン!!
___<__)__________ (__>___
0081nobodyさん
02/06/29 07:19ID:???改行しないヤシまでいるし。
0082nobodyさん
02/06/29 17:52ID:6eV+0rAgOSってどれくらいあるのよ? まさかWindows9xをWebサーバ
にするって話なの?
0083&r
02/06/29 17:56ID:???UNIX系にも一部あるそうですが…。
0084nobodyさん
02/06/29 18:19ID:/fhUzoY0サーバって、flockが効かなかったりするわけ。
0085nobodyさん
02/06/29 21:11ID:Nqaw2LrM0086nobodyさん
02/06/30 00:13ID:naYSzTIEhttp://www.rim.or.jp/support/guide/homepage/cgi/index2.html
0087nobodyさん
02/06/30 00:20ID:???どうしても移植性を持たせたいならconfigure/Makefile.PLでもつければ良い。
0088nobodyさん
02/06/30 04:05ID:???多い印象がありますが。
0089nobodyさん
02/06/30 04:45ID:???素人が設置する事の多いアクセスカウンターや掲示板やチャットなら、
flockが使えるかどうかなんて気にせずに、どこでも使えるロックファイル式
にしたいな。
0090nobodyさん
02/06/30 05:37ID:???1 symlink
2 mkdir
3 flock
4 rename
0091nobodyさん
02/06/30 07:57ID:YjReV7q7選択肢を増やしても、素人さんがつかうときに迷うだけじゃないの?
選ぶ基準はなに?
0092nobodyさん
02/06/30 10:18ID:???本当にそんな強固なファイルロックが必要なのかと…
そんだけアクセスあるんかいと…
ログが壊れてもそこそこのバックアップで復旧できるレベルの
CGIじゃないんかと…
0093nobodyさん
02/06/30 11:01ID:???0094nobodyさん
02/06/30 16:11ID:???flockが必ずエラーになるとか全く機能しないなら簡単だけど、
以前の@niftyでは、flockが「突然」壊れるって症状だったので、
自動判別は難しいかも。flockしたサーバと違うサーバで動く
プロセスがだめなのかな?
NFSなのかラウンドロビンなのかその他の複数サーバシステムなのか、
CGI側で判別できましたっけ。
@niftyは最近サーバがZeusに変わって、今の所flock使えてますが。
0095nobodyさん
02/06/30 16:49ID:???ここはわざわざスレッド建てないとファイルロックが解らない馬鹿共の集うスレ
0096nobodyさん
02/06/30 18:12ID:???単にファイル読みこむだけならロックしなくても大丈夫ですよね?
0097nobodyさん
02/06/30 18:33ID:???つーかflockもsymlinkも使えない鯖なんてそう無い
Windows鯖使ってるところなんて・・
0098nobodyさん
02/06/30 19:16ID:???だ か ら 、 あ る ん だ っ て ば 。
symlinkは大抵つかえると思うけど。
>>93
それってルーチンに組み込むってこと?そりゃマズーじゃない?(毎回余計な処理が増える)
チェック用CGIを添付しといて先にチェックしてもらうのいいかも。
汎用性考えるとmkdirをデフォルトにしとくのがいいと思う。mkdirできない鯖ってない・・でしょ?
0102nobodyさん
02/06/30 21:12ID:???0103japh ◆J.5V8ta6
02/06/30 21:29ID:???別のプロセスが書き込んでる最中に読むと、
壊れたデータを読む羽目になることがある
それを防ぐのが共用ロック:
use Fcntl qw(:flock);
open IN, "foofile" or die "ファイルが開けませんな($1)";
flock IN, LOCK_SH | LOCK_NB or die "誰かが書き込んでいる最中ですな($1)";
0106nobodyさん
02/06/30 23:00ID:???0107nobodyさん
02/07/01 01:23ID:???open(ONE, "> one.lock");
flock(ONE, 3);
open(TWO, "> two.lock");
flock(TWO, 2);
print TWO "two";
close(TWO);
print ONE "one";
close(ONE);
↑こんな感じに
0108nobodyさん
02/07/01 01:41ID:???それでロックしてるの? もっと基本から確認してみては?
0111nobodyさん
02/07/01 02:27ID:???おまえも気づけYO!
0112nobodyさん
02/07/01 22:52ID:???http://tako.2ch.net/test/read.cgi?bbs=perl&key=963036704&st=33
0113nobodyさん
02/07/02 12:38ID:3nOaRL0G0114nobodyさん
02/07/02 17:44ID:???http://natto.2ch.net/perl/kako/963/963036704.html
0115nobodyさん
02/07/04 16:41ID:???・・・と煽ろうと思ったら,レベルの低いスレだったのね.失礼.
0116Hideki ◆wtRzKEV2
02/07/09 09:11ID:???3秒で消し去るのって問題ありでしょうか?
とほほとか見て作ってみたんですけど指摘があればお願いします。
(my $mode, my $file, @_) = @_;
while(!mkdir("$file.lock", 0755))
{
sleep(1);
rmdir "$file.lock" if(time - (stat "$file.lock")[9] > 3);
}
open(DATA, "$mode$file");
print DATA @_;
close DATA;
return rmdir "$file.lock";
0117Hideki ◆wtRzKEV2
02/07/09 09:12ID:???0118nobodyさん
02/07/09 09:31ID:zyHRUAZm始めて裁判見てきたけど、ひろゆきって2chでの中傷について、「おいらは第三者だもんねー」ってな主張してたけど、裁判官に一喝されてた。
どうもひろゆきが企業の中傷を禁止してないことと、削除依頼を自分の意思で突っぱねたことで、当事者と判断されてる感じ。
でも裁判官も他の掲示板と2chは同じには扱っていないみたいだったから、他の掲示板には影響ないと思うけど。
それにしても、ひろゆきの顔はイベント板のタイトルに使ってる写真と全然違うのに驚いた。
あの写真は「勝負写真」なんだろうけど、あれじゃ詐欺だよ。
実物は深海魚みたいな顔だった。
0120Hideki ◆wtRzKEV2
02/07/09 18:23ID:upY+9e5f0121nobodyさん
02/07/09 18:54ID:???指摘する前に質問させてくれ。
これはソースの一部分か? どうみても独立したソースじゃないよな。
なぜファイルロックにmkdirが有効なのか理解できてるのか?
0122Hideki ◆wtRzKEV2
02/07/09 20:00ID:upY+9e5fみたいに渡す構成です。
mkdirを使えば
-> OS処理なので2つのプロセスが両方とも実行ができない。(Windows, UNIXで使える)
-> mkdir以下のコードはひとつのプロセスが実行する保証が得られる
-> mkdirできない間(rmdirが実行されるまで)は他のプロセスは待つ
-> mkdirできれば、ファイルを書きに行く。
-> もし異常終了か何かでロックディレクトリーが残っていれば3秒以上経った物は不正なロックとして強制削除。ファイルを書きに行く。
という構成で書いたのですが、どこら辺が話にならないのでしょうか?説明お願いします。
0123nobodyさん
02/07/09 20:14ID:???ファイルロックを実行して、目的のファイルデータを読み書きするのに要する
時間は処理の混み具合によっては3秒以上かかる可能性もある。もし3秒以上
処理にかかったら他のプロセスにデータを壊される可能性あり。
ファイルロック以外の部分でも書き込み途中でシステムがダウンしたらデータが
壊れる可能性もある。
0124Hideki ◆wtRzKEV2
02/07/09 20:56ID:???秒数で攻めたらいたちごっこですね。
壊す危険を冒すよりは、書き込みを中止する方がいいかもしれませんね。
> 途中でシステムがダウンしたら
そりゃopen後書き込む前に刺さりゃー、何のロックしても無駄ってヤツだ。
0125nobodyさん
02/07/09 22:36ID:???Hideki ◆wtRzKEV2 を叩くスレはここ?
0127nobodyさん
02/07/09 23:05ID:???そう思うならそれで良い、どれだけデータの安全と整合性を保障したいかだから。
そう言う人が秒間50アクセスのDBを管理するなんて事も珍しいでしょうし。
取り合えず
statの取得とrmdirがシステムコールレベルでアトミックになされる保障は
何処にも無い。
消そうとするロックディレクトリが正常かどうかの判断が出来ていない。
よって
>rmdir "$file.lock" if(time - (stat "$file.lock")[9] > 3);
この行は有っても無くても同じ
0128nobodyさん
02/07/09 23:07ID:???基本的に動作と確認が一発で出来る様な
アトミックなシステムコールを使わなきゃ駄目です。
ifで調べてから、動作なんてその間一万年掛かるかも知れないし
0129Hideki ◆wtRzKEV2
02/07/10 00:11ID:???0130nobodyさん
02/07/10 00:16ID:???0131Hideki ◆wtRzKEV2
02/07/10 00:22ID:???同次元の突込みが無いので自分のためのスクリプトしては問題は無いと思った。
つーか、てめーはだれだ!ププッじゃねぇぞ、コルゥァ!
>> 途中でシステムがダウンしたら
>そりゃopen後書き込む前に刺さりゃー、何のロックしても無駄ってヤツだ。
この考え方からしてまだまだだよな。元データを壊さない工夫がないって言い
たかったのに…。
0133Hideki ◆wtRzKEV2
02/07/10 00:35ID:???そうです。まだまだこれからです。まだ若いので。
おおー。まだいるんか。
も1つヒントというか助言だが、mkdir より symlink または rename が
いいと思うぞ。なぜかと言うと mkdir より軽いからだ。なぜ軽いかというと
ファイルシステムを勉強すればわかる。
ただし、symlink は環境によっては使えないから rename を使ったほうがい
いということだ。
最後に、プロは完璧に近いものをストックとしていくつかもっているけど
ここじゃ披露する気にはなれないということを言っておこう。
0135nobodyさん
02/07/10 00:49ID:???0136nobodyさん
02/07/10 00:49ID:???0137nobodyさん
02/07/10 00:49ID:???0138nobodyさん
02/07/10 00:50ID:???0139nobodyさん
02/07/10 00:53ID:???http://www2q.biglobe.ne.jp/~terra/cgi/lockfile.htm
ユーモアのあるページだなぁ。この人は基本的な関数の実行結果の真偽を
使うことも知らないのか…。
こういうページが氾濫しては…。
0141nobodyさん
02/07/10 02:06ID:???dat 落ち前に読んでおけ
http://pc.2ch.net/test/read.cgi/sec/1025671013/349-
0142nobodyさん
02/07/10 02:35ID:???0144nobodyさん
02/07/10 03:04ID:???ブログラマにはギャグセンスも必要っと φ(。。) メモメモ
0146nobodyさん
02/07/10 10:54ID:???(゚Д゚)ハァ? >>142が言ってるのはファイルに直接アクセスなんかしないで
排他処理が元からきちっと実装されてるDBMS使えってことだろ。
まあDBMSが使えるサーバなんて限られてるしこのスレ的にはスレ違いだとは思うが。
0147nobodyさん
02/07/10 15:23ID:???MySQLやらPostgreSQLが〜となるとたしかにアレだろうけど、
BerkleyDB とかなら OS 標準で入っていることも非常に多いし、
Perl からでも使えるしナー。
0148115
02/07/10 16:43ID:???> テーブルの真中には大きなスパゲティの皿が置いてあります.
> またN本のフォークがあって哲学者と哲学者の席の間に置いてあります.
> 哲学者は思索を続けていますが,お腹がすくと両側のフォークを取って
> スパゲティを食べます.お腹が一杯になると食べるのを止めてフォークを返します.
> 哲学者は紳士ですから,お腹が空いていても両方のフォークが手に入るまでは待ちます.
これか。このスレとは微妙に方向性が違うような。
0152nobodyさん
02/07/10 18:38ID:???MySQL が BerkleyDB の機能を使ってトランザクションを実現
しているくらいなのに、lock やってないわけなかろ。いつの
version の話してるの?
http://www.sleepycat.com/docs/reftoc.html
http://www.sleepycat.com/docs/ref/lock/intro.html
見て出直してこい。ちなみにこの document は 4.0.14 のだけど、
3.x のころからしっかり lock subsystem がある。
0153nobodyさん
02/07/10 21:53ID:???OS標準で入ってるつーと
http://www.freebsd.org/cgi/cvsweb.cgi/src/lib/libc/db/README?rev=1.1&content-type=text/x-cvsweb-markup
とかVer 1だろ。
perlのDB_Fileで2や3も使えるけど、インターフェースは1でサポートされてる部分しか使えねーはずだが。
0154nobodyさん
02/07/11 02:02ID:???http://search.cpan.org/search?dist=BerkeleyDB
使えば?
あと、FreeBSD では完全に標準な状態ではたしかにそうだけど、ふつう
ports で 3.x が入ってくるし、Debian でも完全に標準では 2.x でふつう
3.x、RedHat では完全に標準で 3.x が入る
0155nobodyさん
02/07/11 04:50ID:???それなら車輪の再発明は止めて最初からDBMSを使うべきというのは
反論しようのない正論。しかも、リソースのありかまで教えてくれているし。
ただ、こういう極めて的確な回答があると、この手のスレはつまらなくなるね…。
0157nobodyさん
02/07/11 09:23ID:???0158nobodyさん
02/07/11 11:11ID:???0159nobodyさん
02/07/11 16:21ID:???0160nobodyさん
02/07/11 21:02ID:???0161nobodyさん
02/07/12 18:11ID:???# 排他処理をしたいです。
# ローカル環境(WindowsMe+Apache+Cygwin付属のPerl)では成功するのですが、
# サーバで実行するときには、必ず失敗します(エラー表示部が実行されます)。
# もし落ち度がありましたらご教授ください。以下要所の抜粋です。
sub create_lock {
my ($lockfile, $retry) = @_;
while (!mkdir($lockfile, 0755)) {
if (--$retry <= 0) {
return undef;
}
sleep(1);
}
return 1;
}
sub remove_lock {
my ($lockfile) = @_;
rmdir($lockfile);
}
#上記関数の利用例
my $lock_handle = &create_lock("./lockfile", 5);
if (not $lock_handle) {
&print_error($resource{writedatafailed});
}
#ここで処理する
&remove_lock($dir_lock);
0162nobodyさん
02/07/12 19:10ID:???ディレクトリに書き込み権限がない。
既にロックされている(./lockfileが存在する)。
のどちらか。
&create_lock("./lockfile", 5);
と
&remove_lock($dir_lock);
のファイル名が…
0163nobodyさん
02/07/12 19:38ID:???ご指摘ありがとうございます。(;ワ;)
今夜さっそくディレクトリの書き込み権限のチェックをしてみます。
えーと、下の $dir_lock は貼り付け時に直し忘れました(^^;)
混乱させてしまったようで、すみません。
あとでまた結果報告しにきます。
0165nobodyさん
02/07/18 03:33ID:???open(OUT, "+< outfile.txt");
flock(OUT, 2);
truncate(OUT, 0);
seek(OUT, 0, 0);
print OUT "........";
close(OUT);
の欠点を教えてください。
お願いします。
0167nobodyさん
02/07/18 13:34ID:???0169nobodyさん
02/07/18 14:56ID:???flock(OUT, 2);
seek(OUT, 0, 0);
print OUT "........";
truncate(OUT, tell(OUT));
close(OUT);
書き込みが終わってからtruncate()したほうが安全でちょっと速いみたい。
truncate(FILE, tell(FILE)) : 56 wallclock secs ( 8.21 usr + 39.26 sys = 47.47 CPU) @ 210.67/s (n=10000)
truncate(FILE, 0) 60 wallclock secs ( 8.43 usr + 42.72 sys = 51.15 CPU) @ 195.49/s (n=10000)
0170nobodyさん
02/07/18 15:36ID:???正確にはsyswriteするか$|=1してバッファ使わない様にした方が良いけど
0171nobodyさん
02/07/18 15:38ID:???前提が変なのに何をどうしたいのやら
0172nobodyさん
02/07/18 15:41ID:???0173fusianasan
02/07/18 16:45ID:???だれに言ってるんだ? わたしの記憶が確かなら>>170に定数って書いてるYO!
0174nobodyさん
02/07/18 17:11ID:???( > v<)ノ タマンネー♪
0175nobodyさん
02/07/18 17:30ID:???0177nobodyさん
02/07/18 17:42ID:???0178nobodyさん
02/07/18 19:10ID:???0179nobodyさん
02/07/18 23:34ID:???0180nobodyさん
02/07/18 23:43ID:???漢字で書いたら一緒だけど。
ま、もう当分この板はこんな調子でしょ・・・。
0181nobodyさん
02/07/19 01:05ID:???0183nobodyさん
02/07/19 02:38ID:???他のプロセスとの関係とかあります?
0184nobodyさん
02/07/19 02:45ID:???>>1参照。
どんな環境でもつかえてっていうのが、このスレの主題。
flockは環境によってはつかえない。
flockつかえるなら、それでいい。
0185行番号でるかな
02/07/19 03:00ID:???01 open FH,"<./hoge";
02 my @hoge = <FH>;
03 close FH;
04 # @hogeを加工、比較的重い作業
05 open FH "+<./hoge";
06 flock (FH,2);
07 # 書き込み
2行目で配列に全部読み込んでいる、hogeの内容全部がオンメモリな状態。
今10個のプロセスが一斉に読み込みを行ったとする。
つまり10個のプロセス全てが同じ内容の@hogeを得る。
全てのプロセスが完了した時のhogeの内容はどれか一つの
プロセスの内容しか反映されて居ないだろう。
0186183
02/07/19 03:17ID:???どこかのサイトに読み込みオープンでもflockすべきだと
書いてあったのが気になっていたんですが、
そういう場合のことだったんですね。
ありがとうございました。
0187nobodyさん
02/07/19 14:05ID:???0188nobodyさん
02/07/19 15:23ID:H65klWUwこれじゃだめか?
0189nobodyさん
02/07/19 15:44ID:???まあ、可能性ははるかに低くなると思うが。
0191nobodyさん
02/07/19 19:14ID:g9uMB3Mk同じtimeでも唯一のプロセスしかロックできないから大丈夫でない?
1秒内にロックを解除しないままプロセスが死んだ時ってこと?
0192nobodyさん
02/07/20 21:32ID:???0193nobodyさん
02/07/25 16:40ID:Ong5dr5a1.ユニークなファイル名を作り書き込み。
2.指定のファイル名にrename
にしときなさいってこった。
0195nobodyさん
02/07/26 01:04ID:???書き込み中のプロセス事故死に対応して100点。
0197nobodyさん
02/07/26 03:55ID:???sub unlock{
省略
}
この構文の意味がわからんから教えてくれ
unlock関数とif文が何で一緒になってるんだ?
0198nobodyさん
02/07/26 05:36ID:???ちょっと聞いた奥さん教えてくれ!
ぷぷぷ
0200nobodyさん
02/07/26 11:19ID:???読み込み処理のときにはしなくてもいいんですか?
0202nobodyさん
02/07/26 13:35ID:NvB7dZaP=
if($lockkey) {
&unlock;
}
0204nobodyさん
02/07/28 16:44ID:???それでもタイムアウトまでは待つのでは?
あ、正常な処理中にタイムアウトを超えてしまった場合が問題なのかな?
完璧を追求するのなら。
0205nobodyさん
02/07/29 14:41ID:???0206nobodyさん
02/07/29 14:47ID:???0208nobodyさん
02/07/29 15:15ID:???のページでロックの仕方が紹介されていたので使わせてもらおうと思いました。
で、「古いロックファイル(ディレクトリ)の削除」の項目にある、
$retry = 5; # リトライ回数セット
while (!mkdir($lockdir, 0755)) { # 作成。出来なければ待つ
if (--$retry <= 0) { # 5回ダメなら
if (mkdir($lockdir2, 0755)) { # ロックを消すための排他
if ((-M $lockdir) * 86400 > 600) { # 作成時間が10分以上前なら
# ロック入れ替え
rename($lockdir2, $lockdir) or &error("LOCK ERROR");
last; # 一連の処理へ
}else{ rmdir($lockdir2); } # 部分ロック削除
}
&error("BUSY"); # あきらめる
}
sleep(1); # 1秒待つ
}
一連の処理
rmdir($lockdir); # 削除
とりあえず、これ使っておけば大丈夫なんでしょうか。
2ちゃんねるみたいな同時アクセスが凄い場所でない限り。
0212nobodyさん
02/07/29 15:55ID:yLhb3gGL使ってるカウンター(Perl)見たら、
ロックファイル作成
↓
ファイル読み込み
↓
ロックファイル消す
↓
カウントUP
↓
ロックファイル作成
↓
ファイルに書き出し
↓
ロックファイル消す
といった流れになってたんだけど、初めのファイル読み込みの時にもロックは必要なの?
0215nobodyさん
02/07/29 16:32ID:???0221nobodyさん
02/07/29 22:13ID:???0222nobodyさん
02/07/29 22:15ID:???0225nobodyさん
02/07/30 09:03ID:???0226nobodyさん
02/07/30 09:52ID:???0227nobodyさん
02/07/30 11:37ID:???0228nobodyさん
02/07/31 23:34ID:EOzgSn6U0229nobodyさん
02/08/01 02:00ID:DTOpJumx@open直後
Aprint直後
Bclose
A、A〜Bでしょうか?
でもopenでクリティカルな場合に吹っ飛ぶこと考えると…@?
0230nobodyさん
02/08/01 03:58ID:???サーバの正常なタイムアウトなら、書き込みのシステムコールの
途中で止まったりしないでしょう。数回に分けて書き込んでたら、
止まるけど。サーバの容量制限に引っ掛かって止まる事もあるし。
>229
書き込むときに上書き(>)で開くと内容が消えるので、その直後に
止まったらアウト。
どうしてもログを守るんだったら、かならずtempファイルに書き
出して、書き込み成功を確認した後にrenameすることが必要。
ファイルサイズを計ってサイズが異様に小さいときは失敗だし、
内容をチェックすれば完璧。
これならrenameの瞬間に電源が切れるか、HDDがクラッシュする
くらいの事がなければ、壊れないはず。(バグは除く)
どのみち定期的なバックアップは必要かもね。
0232193
02/08/01 19:06ID:W9oFKOXJだから〜。
処理ロックのファイルロックは当然かけておいて、
書き込み時はユニークファイル名に書き出してrename
ってこったよ。
0234nobodyさん
02/08/03 18:57ID:???>>1-233
この調子でがんばれ糞ども
0235228
02/08/03 20:27ID:npWjw1lcたまにログファイルが途中でぶち切れちゃうんです
ファイルアップありだから
でかいファイルをアップロードした時に
途中でタイムアウトするのかと思ったんですが
そうでもないんですね・・・
open(DB,"+<$logdir$log_d") || &error('ファイルエラー error_24');
flock(DB, 2);
my @lines=<DB>;
unshift (@lines,$thred);
seek(DB, 0, 0);
print DB @lines;
truncate(DB, tell(DB));
close (DB);
これ問題ないですよね?
なんでだろ・・・
flock使えない鯖なんでしょうか?
他に原因は考えられます?
0237228
02/08/04 07:59ID:xc+iopog50件ずつにログを区切ってるんで
読み込んでるのは
書き込み50件分のデータです
スレッドのタイトル一覧も表示しないといけないし・・・
0238228
02/08/04 08:03ID:xc+iopogflockが使えないんでしょうか?
それかtell(DB)の値がおかしくなることがあるのかな?
0239nobodyさん
02/08/04 12:11ID:???> seek(DB, 0, 0);
> print DB @lines;
> truncate(DB, tell(DB));
先頭にseekした後に、truncate(FH, tell(FH)) したら当然ファイルサイズ0に
なるわけだが。
0240230
02/08/04 12:57ID:???my @lines=<DB> or &error('読み込みエラー');
としてみては?
読み込んだ大きなファイルの方にメモリを食われてるのかもしれず。
システムコール(ここではファイル操作)は常に失敗の可能性を考えて
おいたほうがいいかと。flockやprintもね。
0241nobodyさん
02/08/04 13:14ID:???もうちょっと問題切り分けた方が良いよ
マルチパートだと思うんだけど、変なモジュールを使って
データ千切れちゃってるとか。
Niftyはflock空振りサーバの代名詞だけど大丈夫?
適当にsleepしてウェイトかけながらテストするとか
シグナル関係全部無視するとか
基本的に共用ならサーバからkillされる様な使い方は
間違ってると思うよ
もし自分のなら、さっさとコネクション切ってじっくりと作業すれば
良いだけなんだけど
サーバのBBSとかFAQは読んでる?
>>239
それは print 〜 が有るから問題無い
と言う事で、一応。
0243nobodyさん
02/08/04 15:21ID:???0244228
02/08/04 21:59ID:etatASlj最初から書いとくべきだったんですが
説明を付け足すと
2chタイプの掲示板なんです
でログファイルへの書き込みはこの部分だけです
カウンターなんかも同じ方法で書き込みしてるんですが
それは飛んだことないんです
で、ログファイルへの書き込みが処理の最後の方なので
遅い回線でファイルアップした時にデータを送るのに
時間がかかり途中でCGIが止まる事があるのかな?
と考えてたのです(最後の方の処理のログファイルが影響受けやすいと)
でも、どういう条件でログが消えるのかは特定できてません
スレッド50件記録のうちの途中(全部じゃないです。例えば36件目とか)で
消えてしまいます(メッセージが途中までしかなかったり)・・・
(レスは別ファイルなのですが、そっちは消えません)
>読み込んだ大きなファイルの方にメモリを食われてるのかもしれず。
そういう制限もあるんですね試してみます
>もうちょっと問題切り分けた方が良いよ
でも、書き込みしてるのこの部分だけなんですよ
やっぱflockが使えなくて
他のプロセスの書き込み中のデータを読み込んでるとログが途中で消えますよね?
でも、カウンターは消えないんですよ・・・
(それともそのうち消えるんでしょうか?ファイルサイズが小さいから確率が低いだけ?)
>サーバのBBSとかFAQは読んでる?
すいません、その辺、勉強してきます
0246230
02/08/05 01:30ID:???1.flockが利かない場合は、まるっと新規発言が記録されないか、書
き込みの後のtruncateで半端な位置で切られるわけで、それぞれの
発言内容の量にさほど違いが無いなら、48〜50発言目くらいの後ろ
の方で切れるはず。
2.新規発言の処理に問題あるなら、unshiftで入れた1発言目(あとで
気が付いたなら数発言目)で切れるが、その後ろの発言まで消える事
は無い。
3.書き込みが全面的に失敗し、書き込まれて無いのに切り詰めれば
ログ丸ごと消える。(ずっとあとになって気が付けば36発言目になっ
てたりするが)
というわけで、36発言目で切れるなら問題は
1.読み込み(my @lines=<DB>)
2.書き込み(print DB @lines)
3.切り詰め(truncate(DB, tell(DB)))
の3個のどれかが失敗してると考えられるよね。それぞれ失敗時には
エラーにしないと。で、これらが失敗する原因は、メモリ使用量や
ディスク容量の制限、あるいはサーバの混雑にありそう。
途中まで書き込んでprintが失敗してるんなら、tempファイル式にす
るしか無いけど、まずは上記の対策してから。
0247228
02/08/06 00:52ID:eY1Nkha6にしたら
最初の一行しか読まないんですが・・
すいません・・・
0248nobodyさん
02/08/06 01:13ID:???(@lines=<DB>)
その他力本願ぶりじゃ先は真っ暗っぽいね
0249228
02/08/06 01:14ID:HdiBMgeWちゃんと動きました
or と || とは違うんですか?
はぁ・・
0250228
02/08/06 01:29ID:AoKqt/prありがとうございます
何が眠たいんだ?
my (@lines=<DB>) || &error('読み込みエラー');
で動いてるんだが、向学の為に教えて欲しい
orは||より優先度がずっと低いんだよ。
だから
@lines = <DB> or error;
は
(@lines = <DB>) or error;
と評価され、
@lines = <DB> || error;
は
@lines = (<DB> || error);
と評価される。
||演算子のオペランドはスカラコンテキストで評価されるから、
結果として一行しか読み込まれないことになる、というわけね。
>>252
< my(@lines = <DB>)
> (my(@lines) = <DB>)
優先度を云々するのなら、= と || および = と or について言わないと意味ナイだろ。
そういえばそうだ。肝心な所が抜けててごめん。
>>253 追記
とりあえず、代入演算子は比較的優先順位が低くなってるんだよ。
例えば、算術演算子や比較演算子などは全て代入演算子より優先度が高い。
だからこそ
$foo = 100 + 200; という式が
($foo = 100) + 200; ではなく、$foo = (100 + 200);と評価される。
で、||や&&といった演算子は代入演算子よりも優先順位が高いため、
加算演算子と同様の評価順序になるってわけ。
しかしながら、orやandといった演算子の優先順位は代入演算子のそれより低いので、
このケースの場合は期待通りに動くわけだね。
詳細についてはついてはperldoc perlopを参照のこと。
0257228
02/08/10 00:33ID:???open(LOG,"+<$log") || &error('ファイルエラー');
flock(LOG, 2) or &error('ロックエラー');
my @lines = <LOG> or &error('読み込みエラー');
〜〜〜更新処理〜〜〜
seek(LOG, 0, 0);
print LOG @lines;
truncate(LOG, tell(LOG));
close (LOG);
こんな感じです
やっぱり同時刻に書き込みが集中した時に消えるようなので
KENT式mkdirロックを少し改造したものをあわせて使ってます
そのまま使うとエラーでロックを外した瞬間に書き込みが重なってしまうようなので・・・
ありがとうございました
0258230
02/08/10 06:54ID:???>そのまま使うとエラーでロックを外した瞬間に書き込みが重なってしまう
ロックを外したら、もはやそのプロセスは書き込まないはず。
まさか&errorでexitせずに、実行続けてるとか?
mkdir式が有効なのは、flockがダメだったからかもしれないが、
処理が遅くなるのとタイムアウトがある事で、読み書きが集中
しないようになった効果かもしれない。
質問者は問題が解決しさえすればいいんだが、
flockとmkdir式の併用なんて気持ちわるい結末だなぁ。
0259228
02/08/10 18:58ID:???どんなエラーでもロックを外してしまうので
書き込み中の人がいて、それ以外の人がエラー出してロックを外してしまう
というのが問題でした
上で書いてるのはちょっと違いました。。
いろいろ教えて頂いたのに、はっきり原因を解明せずに
気持ち悪い結末にしてしまって申し訳ないですが
上のflockのみではprintで失敗したらどうしようもないのなら
mkdirを併用する方法はいいんじゃないかと思うんですが・・
0260230
02/08/10 22:16ID:???書き込み中の人がいるとしたら、その人しかロックが成功していないので、
それ以外の人がロックを外す事はありえないのが排他制御。
mkdir式の場合、ロック成功したプロセスがエラーで外すなら問題ないわけ。
通常、ロックを成功してないプロセスがロックを外すようなのはバグ。
flockの場合はロックかけたプロセス以外は外せないよ。
> printで失敗したらどうしようもない
mkdirを併用しても同じ状況だけど。
print LOG @lines or &error('書き込みエラー');
でOK。truncateする前にやめればデータは壊れない。
とにかく、mkdir式にするならflockは必要ないので消そうよ。
0261nobodyさん
02/08/11 12:39ID:???0262nobodyさん
02/08/11 12:53ID:???0263nobodyさん
02/08/11 13:45ID:???0264nobodyさん
02/08/11 13:46ID:???0265KENT
02/08/11 15:40ID:???0267nobodyさん
02/08/11 19:41ID:???だから初めにflock効いてるのか調べてと言ってるのに
空振りしてるんだよ、それ
他のファイル編集部分は時間的にロック無しでも動いてるだけだよ多分
0268nobodyさん
02/08/11 21:39ID:???俺は断言してないよ、忙しかったしよって感じ
0269nobodyさん
02/08/14 01:12ID:???排他処理とはちょっとズレるかもしれないが、これは立派にシステム上に矛盾が起きてるんだから、"バグ"ではないにしろ、立派な不具合だよな…
この不具合って、そんなに難しいことなのかな…
あたりまえのように、こういうのは想定しないかな?
Kentのスクリプトって、こういうところが馬鹿だよね。
0270nobodyさん
02/08/14 01:45ID:7AoVgCGeこのまとめてロックっていいんですか?
0271nobodyさん
02/08/14 02:02ID:???,一-、
/ ̄ l | / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
■■-っ < んな こたーない
´∀`/ \__________
__/|Y/\.
Ё|__ | / |
| У.. |
0272nobodyさん
02/08/14 02:05ID:7AoVgCGe0273nobodyさん
02/08/14 02:14ID:7AoVgCGe0274nobodyさん
02/08/14 04:31ID:???0275nobodyさん
02/08/14 20:00ID:DbQN4DsP0276nobodyさん
02/09/14 03:01ID:???0277nobodyさん
02/10/01 08:47ID:OVvB7u9F強力なロックだ
0279名無しさん@お腹いっぱい。
02/10/01 16:34ID:???漏れは開きすぎちゃったよ。windows再起動した。
皆気をつけろよ。中のどれか開いたりしたら、国際電話だぞ。
0280名無しさん@お腹いっぱい。
02/10/04 08:00ID:???心ある人は、rubyスレにお礼参りしてください。
0282nobodyさん
02/10/11 23:24ID:0pBUR/gh0284nobodyさん
02/10/15 14:15ID:???2chの負荷でロックなんかしたら使い物にならん
壊れてたら読み直せばすむことだし
0285nobodyさん
02/10/15 18:19ID:jOp8uFKz0286nobodyさん
02/10/16 11:23ID:???一時ファイルを作って書き込み終わったら
subject.txtにリネーム
renameのアトミック性に頼ってるわけだな
datはふつうにflockしてるだけ
0287nobodyさん
02/10/22 13:32ID:???ロック機能作る。
理論的 このスクリプト完璧。
でも どうテストする。
アルバイト100人雇う。
100人いっせいにアクセスする。
そんな 手間かけられない。 どうする。
2ちゃんねるに晒す。 それ怖い。 どうする。
0291nobodyさん
02/10/27 19:23ID:zFNcoqUs別人ですが、読み込んだものを加工してまた書き込む場合には
読み込むときにもロックが必要なんですね?
単に読み込んで、例えば表示したいだけで
加工もしない場合は必要ないんですよね。
0292nobodyさん
02/10/27 21:19ID:???0293nobodyさん
02/10/27 22:41ID:???そうすりゃ一人でもテストできるだろ。
0295nobodyさん
02/10/29 01:24ID:3RRgraL5flock(XX, 2)
書込中だから書込読込ロック、あとから来たら待つ。
とあるのですが、待つってどのくらい待つことが出来るのでしょう…?
上限や目安みたいなものはあるのでしょうか?
実行者が我慢できなくなってkillするまで、ずっと待つよ。
で、それじゃこまるからってんでブロックしないモードがある。
use Fcntl qw(:flock);
flock FH, LOCK_EX | LOCK_NB or die "ロック失敗:$!";
0298nobodyさん
02/10/29 09:56ID:???ブロックして待ったほうがましだが
0299nobodyさん
02/11/03 16:56ID:???rename を使った完璧なファイルロックが完成してしまいました。
0300nobodyさん
02/11/03 18:41ID:???0301nobodyさん
02/11/05 18:35ID:5Ci8Aq1y0302perlお勉強ちゅー
02/11/29 01:12ID:vd7dmowTこんな感じかな、
my($process)=$$;
open (IN,"data.txt");
flock (IN,2);
open (OUT,">$process.tmp");
flock (OUT,2);
#hogehoge処理
close (IN);
close (OUT);
rename ("$process.tmp","data.txt");
不安なんですけど、これで良いのでしょうか?皆様。
0303perlお勉強ちゅー
02/11/29 01:54ID:???0304私も勉強中
02/11/29 17:19ID:???から
rename ("$process.tmp","data.txt");
までの間に、他のプロセスが open (OUT,">$process.tmp") を
実行してしまい、$process.tmpが空になる可能性がある。
※open (OUT,">$process.tmp")した瞬間
$process.tmpのファイルサイズが0になるので、
次の flock (OUT,2) で止めても手後れ。
そんな気がするが、どうだろうか。
0305304
02/11/29 17:25ID:???tmpファイルの名前を毎回変えれば大丈夫か。
0306nobodyさん
02/11/29 19:16ID:???普通に、だめだね。
たとえば、Aプロセスがclose(OUT)まで行く、その直後にBプロセスが
open (IN,"data.txt");、でそのあとAプロセスがrename、Bプロセスは
普通に終了するけど、BのINは、Aが変更を加える前のdata.txtなので
Bがrenameした時点で、Aで加えた変更は破棄される。
0307perlお勉強ちゅー
02/11/30 00:18ID:???ご解説して下さってありがとうございます。
close しなければ rename できないと勝手に
思い込んでいました。(やってみたらできました)
close したときに flock が解除されるのなら
rename 後に close しとけば別プロセスに割り
込まれることが減り、少しはましになるかな。
0308nobodyさん
02/11/30 15:54ID:???> rename 後に close
だめ。 AプロセスがINをopen、直後にBがINをopen、Aがflockして処理を
おえる、Bがflockを獲得して処理を終える。これでも、BのINはAが変更を
加える前のdata.txtなので、同様にAの変更が破棄される。
なおかつ、Win環境だとopen中のファイルのrenameはできなかったような?
0309私も勉強中
02/11/30 16:23ID:???flock(LOCK,2);
open (IN,"data.txt");
open (OUT,"date.tmp");
#hogehoge処理
close (IN);
close (OUT);
rename ("date.tmp","data.txt");
close (LOCK);
INの前にflockするという方向で考えると、こうなるのか?
renameを使ったファイルロックと言っていいのかどうか分からないが。
0311perlお勉強ちゅー
02/12/01 14:43ID:???またもやありがとうございます。
rename 後の close を Windows2000 で試したところ、
ご指摘のとおりエラーになりました。
open してから flock するまでに間が空くのがいけないと思い、
今度はフラグを立てるタイプを考えてみましたが、
フラグが立ってるか判別するまでに間が空く・・・
私には解決が難しいので人のソースでもっと勉強してみます。
0312cron
02/12/02 11:25ID:YojCbNB7Perlでロックしていてもcronでroot権限でrenameしてしまえるみたいなんだけど
Perlで複数のユーザーがどんどん書き加えていくファイルを何分か置きに
root権限で実行したい場合 問題の起こらない良い方法はありますか?
0314cron
02/12/02 13:01ID:YojCbNB7そのコマンドのオプションはCGIで書き込ませたいのです。
0315nobodyさん
02/12/02 14:26ID:Vw2f1Ru9ネタだよなぁぁぁぁ、頼むからネタだと言ってくれー
0316cron
02/12/02 15:25ID:YojCbNB70317☆☆☆☆☆
02/12/02 15:47ID:Z6bI7Cqn0318nobodyさん
02/12/02 22:12ID:???オプティミスティック
オプティミスティック
ペシミスティック
ペシミスティック
ペシミスティック
あー、言いにくい
0319nobodyさん
02/12/06 00:00ID:???あのさあ、rootって管理人のことだろ?
どこの鯖缶が赤の他人にroot権限使わせるってのよ。
やるんなら自鯖立ててやんなよ。
0320Perlお勉強ちゅー
02/12/06 01:16ID:???ファイルの排他処理のキーワードらしいとわかってきました。(つもり)
フラグにするものがアトミックというのは、例えれば、
一組のトランプからはクラブの 1 は 1 枚しか引けないからこそ
目印になるということかな。親元になければ誰もカードを取れないものね。
気になったのは、アトミックがいくつかの使われ方をしている事で、
1 : 現在の ファイル I/O では HDD への読み書きは物理的には一つしかできないことに依存してフラグを立てる。
(HDD の複数ヘッドがばらばらに動いてたらこわいです。)
2 : Perl 上で処理全体をアトミックにと言う場合は、「読み」「処理」「書き」を
「1」に依存して、他人(他プロセス)に口をはさませずに行う。
・・・って感じかな。
# 見当違いでしたらつつしんで怒られます。とほ。
# お勉強中途報告でスマソ。
0321cron
02/12/08 07:08ID:tHo7Ijtwroot権限で当然、自サバでするんだよ
cronのことしらないの?
0322nobodyさん
02/12/08 08:24ID:???cronで動かすプログラムとWebプログラムでのファイルのロックが問題なの?
普通のファイルロックと同じようにやればいいじゃん。
0323319
02/12/08 11:44ID:???自鯖でやるなんて一言も言わなかったじゃないか。
そもそも、自分が鯖缶だとも言ってない。
cronでCGI動かすようにすれば? んで、CGIの方でロックをきちんとすればいい。
0324nobodyさん
02/12/08 11:44ID:???0326nobodyさん
02/12/08 12:11ID:???0327nobodyさん
02/12/08 16:05ID:???> Perlで複数のユーザーがどんどん書き加えていくファイルを何分か置きに
> root権限で実行したい場合 問題の起こらない良い方法はありますか?
「複数のユーザが書き換えるファイル」を「root権限で実行」する馬鹿が本当にいると思ってるのか?
0328山崎渉
03/01/15 13:42ID:???0329nobodyさん
03/01/17 10:53ID:t5G3aPWpとかよくやりますが
close(ABC);
閉じるときも
close(ABC) || &error("error");
とやるべきでしょうか?
closeに失敗することあるんでしょうか?
0330nobodyさん
03/01/17 12:29ID:+SxK8G04非常にいい質問だね。
さ、誰か答えてやんなさい。
0331nobodyさん
03/01/17 13:58ID:???0332nobodyさん
03/01/18 00:49ID:???それがどうファイルロックと関係あるのかと
0333nobodyさん
03/01/18 14:04ID:???処理が終了されて、ロック解除できずロックファイルが残る場合。
0334nobodyさん
03/01/18 17:36ID:???どうして上手くいっているのだろうか?
0339世直し一揆
03/01/30 10:23ID:EZ4VgkoJるな!)
●とにかく気が小さい(神経質、臆病、二言目には「世間」、了見が狭い)
●他人に異常に干渉し、しかも好戦的・ファイト満々(キモイ、自己中心)
●自尊心が異常に強く、自分が馬鹿にされると怒るくせに平気で他人を馬鹿にしようと
する(ただし、相手を表面的・形式的にしか判断できず(早合点・誤解の名人)、実際に
はたいてい、内面的・実質的に負けている)
●本音は、ものすごく幼稚で倫理意識が異常に低い(人にばれさえしなければOK)
●「常識、常識」と口うるさいが、実はA型の常識はピントがズレまくっている(日本
の常識は世界の非常識)
●権力、強者(警察、暴走族…etc)に弱く、弱者には威張り散らす(強い者に弱く
、弱い者には強い)
●あら探しだけは名人級(例え10の長所があってもほめることをせず、たった1つの短所を見つけてはけなす)
●基本的に悲観主義でマイナス思考に支配されているため性格がうっとうしい(根暗)
●一人では何もできない(群れでしか行動できないヘタレ)
●少数派の異質、異文化を排斥する(差別主義者、狭量)
●集団によるいじめのパイオニア&天才(陰湿&陰険)
●悪口、陰口が大好き(A型が3人寄れば他人の悪口、裏表が激しい)
●他人からどう見られているか、人の目を異常に気にする(「世間体命」、「〜みたい
」とよく言う)
●自分の感情をうまく表現できず、コミュニケーション能力に乏しい(同じことを何度
も言ってキモイ)
●表面上意気投合しているようでも、腹は各自バラバラで融通が利かず、頑固(本当は
個性・アク強い)
●人を信じられず、疑い深い(自分自身裏表が激しいため、他人に対してもそう思う)
●自ら好んでストイックな生活をし、ストレスを溜めておきながら、他人に猛烈に嫉妬
する(不合理な馬鹿)
●執念深く、粘着でしつこい(「一生恨みます」タイプ)
●自分に甘く他人に厳しい(自分のことは棚に上げてまず他人を責める。しかも冷酷)
●男は、女々しいあるいは女の腐ったみたいな考えのやつが多い(例:「俺のほうが男
前やのに、なんでや!(あの野郎の足を引っ張ってやる!!)」)
0340nobodyさん
03/01/30 12:26ID:RKDiglA0壊れるという現象が頻発して困ります。
なにか他のいい方法を探しているのですが
書き込み待ちテンプを作るやり方があると聞いたのですが
教えてください。
0342nobodyさん
03/01/31 04:05ID:QdG4FrQHどのようにロックかけるのがのぞましいのでしょうか?
0343nobodyさん
03/01/31 07:27ID:K4VaGHSu0344nobodyさん
03/01/31 20:55ID:???0345nobodyさん
03/02/01 03:10ID:6WMjWs0+∧∧ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
(,,゚Д゚)< みんなで視姦汁!
./ | \________
.______(___/_____
.|03. 2. 2. / AHE |
.|________________|
/\ \
/ \ 2003年2月2日 \
/ Λ_Λ \ .13:00… \
/__( ´д`)_\______________\
| |ゲ.| │ |
| |.ロ | │ 梅田丸ビルの .|
| |ゲ.| │ 電光掲示板に… .|
| |.ロ | │ ..『(゚д゚)ウマー』 |
|γ__ |ゲ.| │ ̄\ / ̄|
| \ |.ロ | │ \_________/ |
| |ゲ.| │ │
|____|__||_|)|.ロ | │ コ ッ プ 1 杯 .│
|□━□ ) │ . ( 約 200ml ) で |
| J |) / ̄ ̄ |. 1 日 分 の * .|
| ∀ ノ < ヒヒヒヒヒ | 黄色ブドウ状球菌 |
| - ′ . \____ | 2 分 の 1 |
| ) │ │
|/. 製 造 ..| │
| . 逝印大阪工場 . | 500 ml |
|____________________|______________|
http://life2.2ch.net/test/read.cgi/offreg/1043075025/l50
0346nobodyさん
03/02/01 03:23ID:???0347nobodyさん
03/02/19 23:23ID:???0348山崎渉
03/03/13 17:22ID:???0350nobodyさん
03/03/22 18:02ID:???0351nobodyさん
03/04/17 00:56ID:s+I4ylgdhttp://www.din.or.jp/~ohzaki/perl.htm#File_Lock
を使おうと思ったんですが、
なにげにperl初心者なんで、その使い方がわかりません。
perlメモには、
$lfh = my_flock() or die 'Busy!';
# アンロックする
my_funlock($lfh);
$lfh にはなにをいれれればいいのでしょう?ファイル名?ファイルハンドル?
0352nobodyさん
03/04/17 02:26ID:???0353山崎渉
03/04/17 11:58ID:???0354351
03/04/17 22:16ID:PczzXVDVどういうこと?
0355佐々木健介
03/04/17 22:16ID:???/_ |
/. \ ̄ ̄ ̄ ̄|
/ / ― ― |
| / - - |
||| (5 > |
| | | ┏━┓| / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
| | | | ┃─┃| < こんなサイトを見つけた
|| | | | \ ┃ ┃/ \ 正直、スマンカッタ
| || | |  ̄ \_________
http://freeweb2.kakiko.com/tama/
0357bloom
03/04/17 22:56ID:ahUYqmP+0358nobodyさん
03/04/17 22:57ID:???0359あぼーん
03/04/17 23:23ID:???http://www.japan.pinkserver.com/yamazaki/saitama/hankaku06.html
http://www.japan.pinkserver.com/yamazaki/saitama/hankaku05.html
http://www.japan.pinkserver.com/yamazaki/saitama/hankaku03.html
http://www.japan.pinkserver.com/yamazaki/saitama/hankaku04.html
http://www.japan.pinkserver.com/yamazaki/saitama/hankaku01.html
http://www.japan.pinkserver.com/yamazaki/saitama/hankaku02.html
http://www.japan.pinkserver.com/yamazaki/saitama/hankaku09.html
http://www.japan.pinkserver.com/yamazaki/saitama/hankaku10.html
http://www.japan.pinkserver.com/yamazaki/saitama/hankaku07.html
http://www.japan.pinkserver.com/yamazaki/saitama/hankaku08.html
0361nobodyさん
03/04/19 13:00ID:EJZQKwDzに載ってる「ファイルを上書きする場合」(↓)
open(OUT, "+< $datafile"); # 読み書きモードで開く
flock(OUT, 2); # ロック確認。ロック
seek(OUT, 0, 0); # ファイルポインタを先頭にセット
print OUT "$data\n"; # 書き込む
truncate(OUT, tell(OUT)); # ファイルサイズを書き込んだサイズにする
close(OUT); # closeすれば自動でロック解除
を参考にして、
「(1)ファイルの中身(データ)を読み込んで、読み込んだデータを加工して、
(3)再度同じファイルにデータを格納する場合」を考えたんだけど、
↓で特に問題ないでしょうか?
$datafile = "data.txt";
open(OUT, "+< $datafile"); # 読み書きモードで開く
flock(OUT, 2); # ロック確認。ロック
@Array_data = <OUT>; # ★追加:(1)ファイルの中身を読み込んで
foreach $values (@Array_data){
#@Array_dataをいろいろ加工; # ★追加:(2)読み込んだデータを加工
chomp $values;
$values = $values * 2;
push (@New_Array_data,"$values\n");
}
seek(OUT, 0, 0); # ファイルポインタを先頭にセット
print OUT @New_Array_data; # ●変更:(3)再度同じファイルにデータを格納
truncate(OUT, tell(OUT)); # ファイルサイズを書き込んだサイズにする
close(OUT); # closeすれば自動でロック解除
0363nobodyさん
03/04/19 19:05ID:???この最中に逝っちゃっても大丈夫?
0365山崎渉
03/04/20 06:00ID:???( ^^ )< ぬるぽ(^^)
0366:
03/04/21 18:06ID:J93Hac+3http://sagatoku.fc2web.com/
あなたの探し物きっとみつかるよ☆^〜^★
0370nobodyさん
03/04/21 23:33ID:???0371nobodyさん
03/04/21 23:54ID:???イヤなら定期的にバックアップ取る処理を組め。
0372nobodyさん
03/04/22 14:19ID:???0373nobodyさん
03/04/22 20:26ID:???0374nobodyさん
03/04/22 20:41ID:???0375っていうか
03/04/24 13:03ID:???これ定説
0376山崎渉
03/05/22 02:08ID:???0377nobodyさん
03/05/22 07:17ID:???if (opendir(LOCK, "lock")) {
closedir(LOCK);
rmdir("lock");
# 処理
mkdir("lock");
}
0378nobodyさん
03/05/22 09:34ID:sAd9/kNTじゃなくて
mkdir("lock", 600)
でした。
0379nobodyさん
03/05/22 10:08ID:???違う。
if (mkdir ("lock", 755)) {
(処理)
}
こう。
mkdirは、ディレクトリの作成に成功すると真が、
失敗すると偽が返ってくる。
0380nobodyさん
03/05/22 13:35ID:2b2Zl4vP?それだけでいいんでふか?
0381nobodyさん
03/05/22 13:46ID:???そのときにネットで見つけたアダルトDVDショップ以前からオナニー用にDVD
が欲しかったのですぐ注文しました、とても安くてびっくりしましたが次の日には
もう届きました私が買ったのは、オナニー、レズ、レイプです毎日オナニーしてま
す。
http://www.net-de-dvd.com/
0382nobodyさん
03/05/22 13:53ID:???ttp://homepage1.nifty.com/glass/tom_neko/web/web_04.html
このへんでも参考に
0383380 じゃないけど
03/05/22 15:06ID:???激しく参考になりますた。謝謝。
ところで
flock() が使えないところで
eval{ if(!(flock(FH, 2))){ &function; } };
とした場合ちゃんとサブルチンに逝ってくれますか?
false は返ってくるんでしょうか?
0384nobodyさん
03/05/22 15:40ID:Mzhw6+0oサンクスコ(・∀・)
0385nobodyさん
03/05/23 13:24ID:ORCLTuvqアンロックする時にrmdirでディレクトリ削除ってことですよね?
>>382のサイト見てないけど…。
0387山崎渉
03/05/28 17:07ID:???ピュ.ー ( ^^ ) <これからも僕を応援して下さいね(^^)。
=〔~∪ ̄ ̄〕
= ◎――◎ 山崎渉
0388nobodyさん
03/05/28 18:03ID:???0389nobodyさん
03/05/31 21:04ID:n0OtuFEQ他のプロセスでロックしてるファイルにアクセスしてもロックがすぐ終っちゃうような…。
どうすれバインダー。
0390動画直リン
03/05/31 21:10ID:1EAhrEiJ0392389
03/05/31 21:45ID:n0OtuFEQ0393nobodyさん
03/05/31 22:08ID:nC5SP5sDロック中に
sleep 60;
0394nobodyさん
03/05/31 23:30ID:???package FileLock;
use IO::File;
my $CAT= '/bin/cat';
sub open_w {
my $filename= shift;
mkdir($filename)unless -d $filename;
my $base= sprintf("%s.%s.",time,$$);
my $cnt= 0;
$cnt++ while(-f "$filename/$base$cnt");
return IO::File->new("$filename/$base$cnt",'>>');
}
sub open_r {
my $filename= shift;
return IO::File->new("|$CAT $filename/*");
}
1;
0395nobodyさん
03/06/01 04:57ID:Hll/ZLYfおぉ!蟻がとう。
0398nobodyさん
03/06/01 21:54ID:???flockと組み合わせて(かつcron回してファイルをまとめつつ)
使ってたんだけど。。。駄目かぁ(´Д`;)
0399nobodyさん
03/06/02 00:36ID:???> mkdir($filename)unless -d $filename;
意味なし。複数のプロセスでunless -d $filenameが成立する可能性がある。
排他制御するにはアトミックにやらないと駄目。
排他制御に強い/弱いは無い。正しいか駄目のどちらか一方、わずかでも可能性があれば駄目ロック。
0400nobodyさん
03/06/02 09:59ID:7y9vki3n--$retry <= 0
なんてやってるの?
$retry--
じゃまずいの?
0401nobodyさん
03/06/02 10:09ID:Ixodm31chttp://www1.free-city.net/home/s-rf9/page006.html
0402nobodyさん
03/06/02 10:20ID:sw1UrgM5( ´∀`)/< 先生もろDVDはどこですか?
_ / / / \___________
\⊂ノ ̄ ̄ ̄ ̄\
||\ \
||\|| ̄ ̄ ̄ ̄ ̄||
|| || ̄ ̄ ̄ ̄ ̄|| ∧_∧ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
.|| || (´Д` ) < http://www.dvd01.hamstar.jp だ!
/ \ \___________
|| ||
|| ||
__ //_ //___
/ // // /
/  ̄  ̄ //
|| ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|| ||
|| ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄|| ||
|| 教卓 || ||
|| ||
0404nobodyさん
03/06/02 10:35ID:azLkJHuzいやいや、なんで<=を使ってるかが知りたいの?
ifって偽だと実行しないでしょ?
$retryは最終的に0になるわけだから、<=は必要ないだろ。
ってかスレ違いって分かってるので、逝ってきます。
0405nobodyさん
03/06/02 10:39ID:7y9vki3nやっぱり逝くしかないな…。
0406直リン
03/06/02 11:10ID:mGHfwiJV0409nobodyさん
03/06/02 12:07ID:???いや・・・だからさ・・・
全体のソース読んでないんで分からないんだけど。
マイナスになる可能性があるかもしれないんでしょ?
--$retry <= 0
この条件だと、$retryがもし0だったら・・・
-1 <= 0
こんな判定になるし。
0が入る訳がないソースだったとしても、
ちゃんと条件書いてる方が、見た目分かりやすいってのもある。
そして、スレ違いだから、やっぱ逝くべき。
0412nobodyさん
03/06/02 12:47ID:YkiHze2nうおっ!キツイ一言だな…。
でもこのスレのヤシらはなんか優しい…。
すっきりしたら逝くから、すっきりさせろYO!
なんで-1になるんだ?
粘着房だな…。
0413nobodyさん
03/06/02 13:02ID:???だから・・・・
--$retry <= 0
↑これだけ見せられて、-1になるか、ならないかって言われても、
分からない訳なのよ。
どのソースみて、言ってる訳?
とにかく、その一行を見る限りでは、-1になる可能性はある。
何度も言うようにスレ違いだから、優しいうちに逝っとけ。
0414動画直リン
03/06/02 13:10ID:mGHfwiJV0416nobodyさん
03/06/02 13:43ID:???気がするであって、気にする奴が本当に気にしなきゃいけない場合はアセンブラで書く。
0417_
03/06/02 14:38ID:???0418_
03/06/02 16:09ID:???0419_
03/06/02 19:13ID:???0421nobodyさん
03/06/17 05:57ID:???これって使っても平気ですか?
0422nobodyさん
03/06/22 16:13ID:???0423nobodyさん
03/07/07 19:32ID:???20 Open "Text1.txt" For Output As #1
30 Print #1,"Write file."
40 Close #1
ファイルロックのためのtmpファイル作成しようと思ったんですが、
プログラム内で擬似マルチタスクを作成している時といないときがあるので、
flock関数みたいなものがあれば効率が上がると思うのですが、
やはりrename形の方が安全で軽いのでしょうか?
0424なぞなぞ先生
03/07/08 06:24ID:???0425nobodyさん
03/07/08 12:02ID:???0427nobodyさん
03/07/08 12:19ID:???0428nobodyさん
03/07/08 15:54ID:???0429nobodyさん
03/07/08 15:58ID:???0431nobodyさん
03/07/10 16:21ID:QDkm5VXPflock使えるサーバなんだけど、書き込み中はロックするっていう
対象のファイルをflockの引数にするのと、別のダミーファイルを
flockの引数にするのとあるでしょ。どっちがいいのでつか。
0432nobodyさん
03/07/10 17:46ID:???処理全体にかけたいなら後者の方が良いかと。
0433nobodyさん
03/07/10 21:42ID:???0435nobodyさん
03/07/11 11:17ID:???0437なぞなぞ先生
03/07/15 06:43ID:???完全に同時にプロセスが発生することはないよね?
マルチタスクってのもマルチスレッドってのも基本的に擬似的に行っているもので、
結局は1つのプロセスが司っている処理って聞いたことがあったような。
そうすると、OSがダウンしない限りrename型の排他処理
rename
open
処理
close
rename
は完璧に有効だと思うんだが。
と思ったけど、それを言い始めたらキリが無いかw
うーん、、、しかしたまに2chで1001を超えるのは何でだろう。
ロック解除してから1001のチェックをしているのかな。。。
最近うなされて困ってます。変な文&長文すまん。
0438nobodyさん
03/07/15 06:44ID:???氏のう。。。。
0439山崎 渉
03/07/15 11:08ID:???__∧_∧_
|( ^^ )| <寝るぽ(^^)
|\⌒⌒⌒\
\ |⌒⌒⌒~| 山崎渉
~ ̄ ̄ ̄ ̄
0440nobodyさん
03/07/15 19:03ID:???レスが1000を超えるのはdatファイルへの書き込みと、
レスポンス数のチェック(書き込み禁止処理)がアトミックにできないから。
実際には、二つの処理に結構な間があると思う。
0441nobodyさん
03/07/15 22:40ID:???| |
∧_∧ | | / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
( ´ー`)// < 先生!
/ / | アトミックって何ですか?
/ /| / \___________
__| | .| | __
\  ̄ ̄ ̄ ̄ ̄ \
||\ \
||\|| ̄ ̄ ̄ ̄ ̄ ̄ ̄|| ̄
|| || ̄ ̄ ̄ ̄ ̄ ̄ ̄||
.|| ||
0442nobodyさん
03/07/15 23:25ID:???他のプロセスが割り込めない極小時間(ワンステップ)で操作。
にしといてくださいな。
0443nobodyさん
03/07/16 07:27ID:???ましてやファイルロックの話題ならなおさら
0444437
03/07/16 08:09ID:???ファイルロック中に何らかの処理(たとえば別ファイルにHTML書き出しやHTML化待ちDATリストへの追加)
をすれば、"アトミック"は存在しないと思うのですが。
下手な考えスマソ。。。
0445440
03/07/16 22:09ID:???ああっと、flockが頭にあったので、、
renameが理想的なロックとして動作するとしたら>>437で可能だと思います。
(OSがlinuxの場合は壊れたりするけど…)
2chとしては、1000で止まらなくても(多少レスが多く付いても)構わないのかも。
(ロックする時間が増える→待ちプロセス数が増える→サーバ負荷が増えるよりは。)
0446437
03/07/17 00:22ID:???2chみたいな大規模な掲示板だとここが問題なんですね。
ぐっすり眠れそうな気がしました。レスありがとうございました。
0447nobodyさん
03/07/19 14:28ID:???スレッドキー(ファイル名)決定と、ファイル作成(書き込み)を別の場所で
行っている事がほとんどなので、同時にスレ立てが発生するとスレッドが
合体する可能性がある。
半年前あたり2chでもちょっと問題になってた。
実際としては2ch以外で問題になることは無いと思うけどね。
0449nobodyさん
03/07/20 09:18ID:???そういうことじゃない。
スクリプトの中でキー決定からファイル作成までの間に
いろいろな処理があって、同時スレ立ての一方がファイル作成前に
もう一方がそのキーのスレがあるか確認して存在しないと
判断してしまう時差の問題が起こりえるということ。
0450nobodyさん
03/07/26 13:13ID:GHzBAdl/具体的に何をすれば良いのでしょうか?
flock と言う名前のディレクトリを
作って、ロックしたいファイルに
置いとけば良いのでしょうか?
すいませんが、まるっきりの初心者ですので、
教えて下さい。
0453_
03/07/26 13:55ID:???0454nobodyさん
03/07/26 18:00ID:???flockするファイルのあるディレクトリのパーミッションは任意たんでよいですか?
自分の中で最高の条件を満たすレンタル鯖がflock使えないとかなりへこむ。。。
結局rename型のlockにしてみたんだが、鯖の負荷とか考えたくないなぁ。
ブロードバンド回線開通したら絶対鯖立てたい。
と言う独り言でした。また来週。
0455nobodyさん
03/07/26 22:03ID:???flockも使うのが最強ですかね?
0456nobodyさん
03/07/26 22:40ID:???0457nobodyさん
03/07/27 01:31ID:???ハァ、Webプログラマーってどうして馬鹿ばっか集まるんだ。
排他制御に強い/弱いはない。正しい/駄目のどちらかだ。
駄目なものをいくつ重ねても駄目なものは駄目。正しい方法を複数使う必要はない。
0458nobodyさん
03/07/27 03:14ID:???0459nobodyさん
03/07/27 09:30ID:???0460nobodyさん
03/07/27 20:51ID:???http://tv3.2ch.net/test/read.cgi/geino/1050253651/377
0461nobodyさん
03/08/04 22:07ID:???0462nobodyさん
03/08/06 01:55ID:pOGj2Sy20463nobodyさん
03/08/06 01:56ID:pOGj2Sy20464nobodyさん
03/08/06 01:56ID:pOGj2Sy20465nobodyさん
03/08/07 14:03ID:fxtSTKINuse Fcntl;
をしといて、
sysopen
を使ってLOCK_EXとか呼べないかな。
0466nobodyさん
03/08/07 14:18ID:???LOCK_EXは定数(を返すだけのsub)
0467nobodyさん
03/08/07 15:00ID:???sysopen FILE,"hoge",O_RDWR|O_CREAT|LOCK_EX;
みたいなことできるかってこと?
試してみてね。
俺は知らん。
0470nobodyさん
03/08/09 22:15ID:???use IO::File::fock;
my $fh = new IO::File::fock('file','>>');
0471山崎 渉
03/08/15 22:42ID:???│ ^ ^ │<これからも僕を応援して下さいね(^^)。
⊂| |つ
(_)(_) 山崎パン
0472nobodyさん
03/08/24 11:20ID:???追記の場合って、どうするのが一番確実で負荷がかかんないんでしょうか?
僕は、データを編集する場合と同じように、以下のようにしちゃってますが。use Fcntl qw(:flock);
#万が一リネーム失敗したときのために、ユニークなファイル名にしておく
$tmpfile = "$datafile".".$$.". time() .".csv";
#ロックファイルを作成する(★注:ロックファイルは、各CSVごとにユニークに)
open (LOCKF, ">$datafile"."_lockf") or die("cannot open:$!");
flock (LOCKF, LOCK_EX); #ロックファイルをflockする
open(IN, "< $datafile") or die("cannot open:$!"); # 読みのみモードで開く
open(TMP,"> $tmpfile"); #テンポラリファイルを作成
while ($line = <IN>){
$line .= <IN> while ($line =~ tr/"// % 2 and !eof(IN));
$line =~ s/(?:\x0D\x0A|[\x0D\x0A])?$/,/;
@values = map {/^"(.*)"$/s ? scalar($_ = $1, s/""/"/g, $_) : $_}
($line =~ /("[^"]*(?:""[^"]*)*"|[^,]*),/g);
#必要なものだけをEUCにして、出力時にSJISにする
foreach $value (@values){
&jcode::convert(\$value, "euc");
};
#CSV形式に変換
$newline = join ',', map {(s/"/""/g or /[\r\n,]/) ? qq("$_") : $_} @values;
print TMP "$newline\n" ;#テンポラリファイルに1レコード書き込み
}
print TMP "新しい行" . "\n";
close TMP;
close IN;
unlink $datafile;
rename ($tmpfile, $datafile) or die ("cannot rename : $!");
close LOCKF;
0473472
03/08/24 11:25ID:xfHM1yWk訂正。
↓これでどうでしょか?
use Fcntl qw(:flock);
#万が一リネーム失敗したときのために、ユニークなファイル名にしておく
$tmpfile = "$datafile".".$$.". time() .".csv";
#ロックファイルを作成する(★注:ロックファイルは、各CSVごとにユニークに)
open (LOCKF, ">$datafile"."_lockf") or die("cannot open:$!");
flock (LOCKF, LOCK_EX); #ロックファイルをflockする
open(IN, "< $datafile") or die("cannot open:$!"); # 読みのみモードで開く
open(TMP,"> $tmpfile"); #テンポラリファイルを作成
while ($line = <IN>){
print TMP $line ;
}
print TMP "新しい行" . "\n";
close TMP;
close IN;
unlink $datafile;
rename ($tmpfile, $datafile) or die ("cannot rename : $!");
close LOCKF;
0474472
03/08/24 11:57ID:xfHM1yWk単純に、
use Fcntl qw(:flock);
open(OUT, "+< $datafile");
flock (LOCKF, LOCK_EX);
truncate(OUT, 0); # ファイルサイズを0バイトにする
seek(OUT, 0, 0); # ファイルポインタを先頭にセット
print OUT "新しい行" . "\n";; # 書き込む
close(OUT); # closeすれば自動でロック解除
・・・・どっちがいいのでしょうか・・・?
0475nobodyさん
03/08/24 12:53ID:???追記なら
use Fcntl qw(:flock);
open(OUT, ">>$datafile");
flock (OUT, LOCK_EX);
seek(OUT, 0, 2); # ファイルポインタを最後尾にセット(念のため)
print OUT "新しい行" . "\n";; # 書き込む
close(OUT); # closeすれば自動でロック解除
--
# 私はこんな感じ(Win不可)
use FileHnadle;
my $fh = new FileHandle($datafile, O_WRONLY|O_CREAT|O_APPEND|O_EXLOCK) or die;
print $fh '新しい行', "\n";
close($fh);
IO::Fileでもいいんだけど、趣味でFileHandle使ってます。
0476nobodyさん
03/08/27 11:26ID:???open(LOG, ">$logfile") or &error("Open Error : $logfile");
flock(LOG, 2);
seek(LOG, 0, 2);
my(@lines) = <LOG>;
(if($agent =~ /MSIE 3/i) { $agent = 'MSIE 3'; }のような置換とか)
while($max-1 < @lines) { pop(@lines); }
unshift(@lines, "$agent<>$os<>$host<>$referer<>$hour<>$doc_uri<>\n");
unshift(@lines, "$addr\n");
print LOG @lines;
close(LOG);
こうすると書き込み時にログが一旦全部消えてしまい、
取得した最後のログ一行(先頭行に最終アクセスIPがあるので正確には二行)のみになってしまいます。
何処が悪いのでしょうか…
因みに元スクリプトではログを配列に読み込んだ時点で一旦閉じ、
処理後もう一度開いて書き込みという風になってたのですが、
これだと処理中に書き込まれたら駄目そうな気がしたので上のように書き換えたのです。
0477nobodyさん
03/08/27 19:09ID:???lockどうこうより、while がおかしいのでは?
$max-1 < @lines がどういう比較かわからんけど、自分で
pop(@lines);して削除しちゃってるじゃないの
常にwhileが真で全行削除になってその後unshiftで2行追加してるだけでは?
0478nobodyさん
03/08/27 21:08ID:???'>'でオープンすると?
・ファイルの中身を切り詰める。
・書き込み専用でオープンする(ファイルが無ければ作成)。
>seek(LOG, 0, 2);
この意味は?
・フィル最後尾にファイルハンドルを移動する。
さすがに読めません。
0479nobodyさん
03/08/27 21:09ID:???flock(LOG, 2);
my (@lines) = <LOG>;
(ロックスレなので、、略)
seek(LOG, 0, 0);
truncate(LOG, 0);
print LOG @lines;
close(LOG);
上の書き方では、seekとtruncateの間で終了させられると、
ファイルの中身が失う危険性があるから、
seek(LOG, 0, 0);
print LOG @lines;
truncate(LOG, ftell(LOG));
close(LOG);
と書くといいらしいです。(実際はどうなんでしょ?)
http://www.kt.rim.or.jp/%7ekbk/perl5.005/perlfaq5.html#How_come_when_I_open_the_file_re
http://www.kt.rim.or.jp/%7ekbk/perl5.005/perlfaq5.html#I_still_don_t_get_locking_I_jus
クックブック 7.11
ttp://homepage1.nifty.com/glass/tom_neko/web/web_04.html
0480479
03/08/27 22:53ID:???間違いでした。以下の通り。
truncate(LOG, tell(LOG));
0481nobodyさん
03/08/28 11:06ID:???だめなの?
0482nobodyさん
03/08/31 01:47ID:3rubdTEFuse DB_File;
use Fcntl;
open DAT,"lockfile";
flock(DAT,LOCK_EX);
tie(%hash,'DB_File',"dbfile",O_RDWR|O_CREAT,0666
---DBM代入処理
としてロックしてました。
lockfileというファイルへの排他ロックを取得しているのは
わかるんだけど、それがどうしてDBMのdbfileへのロックと
なるのかわからん。
0483nobodyさん
03/08/31 04:22ID:???「dbfileを使うプロセスは、かならずdbfileにアクセスする前にlockfileをロックする」
という紳士協定があればうまく行く。
dbfileにアクセスするのが>>482のスクリプトだけの場合も然り。
それでもなぜか分からないなら良く考えてみ。
0484nobodyさん
03/08/31 20:24ID:???ブロッキングを理解すると分かると思います。
flockでロックされると、LOCK_NBを指定していない限り、
排他される側はflock関数の場所で処理を止められます。
0485482
03/08/31 22:31ID:3rubdTEFflockをLOCK_SHでした場合は%hashへの代入はしない。
上を全てのdbfileを使う処理でする。
この順番を守ればflockの段階でブロックしてtieへ進まない。
やっと、すっきりした。
>>483.484さんありがとー
0486nobodyさん
03/08/31 23:56ID:???書き込みできる状態でファイルをオープンしないとロックしない
OSがあるそうです。ご注意あれ。
参考:
同じ(ような)処理をするモジュール。
http://search.cpan.org/author/DHARRIS/DB_File-Lock-0.05/Lock.pm
0487482
03/09/01 01:40ID:???open LOCK,'<lockfile';
ってするてことですね。気をつけます。
このモジュール結構便利ですね。
ありがとございます。
perlの面白みにはまっっていく・・土日外にでてねえ・・
0488nobodyさん
03/09/01 19:13ID:???SYNCがかかったらSHにもどしちゃダメ?
LOCK_EXの時間は短い方がいいとおもうんだけど
0489nobodyさん
03/09/01 22:19ID:???魅力的ですが、共有ロック(LOCK_SH)をしているところに
排他ロック(LOCK_EX)をしようとすると、
ブロックされて待たされることになります。
書き込む事がほとんどないのであれば、
検討する価値はあるかも。
ロックしたら、操作、すぐ開放が基本です。
0490488
03/09/02 11:52ID:???> 排他ロック(LOCK_EX)をしようとすると、
> ブロックされて待たされることになります。
同じプロセスならLOCK_SHからLOCK_EXへ移行できちゃったんですが...
0491nobodyさん
03/09/02 20:13ID:???processA processB
| |
flock(F, LOCK_SH); |
| |
処理 flock(F, LOCK_EX);
| :
| : (ブロックされる)
| :
close(F); 処理 (ここで処理開始)
| |
exit; |
close(F);
|
exit;
0492490
03/09/04 22:14ID:???って事でhttp://www.perldoc.jp/docs/modules/DB_File-1.805/DB_File.poをみると・・・
まともにロックしたかったらBerkeleyDBを使えっと(´Д`;)
0493nobodyさん
03/09/06 01:39ID:A9Khhwgn漏れなら小規模の場合は消えるの覚悟で単純にflockだけ(面倒)。
中規模以上はDB立ててDBのLOCKで対処。
これじゃいかんのか?
0494nobodyさん
03/09/06 02:09ID:???0495nobodyさん
03/09/06 03:10ID:???flockで消えちゃうのは、何かお前のやり方に問題があるんだと思うぞ。
システム自体がflockの堅牢性に頼っていると言うのに。
0496nobodyさん
03/09/07 02:25ID:???0497nobodyさん
03/09/07 10:06ID:???限界って?
Windowsやover networkでうまく働かない以外に何か問題あったっけ?
だいたいflock使えねーとか言ってるヤツのコードみると書き方間違ってる
だけだったりするんだよな。
ごちゃごちゃ言う前にモジュール使えってのはまぁ同意だけど。
0498nobodyさん
03/09/07 14:44ID:AN0xO5Efありますよ。ご自分でお調べください。
0499nobodyさん
03/09/07 15:01ID:???あとは昔のOSでバッファをフラッシュしないくらいしか思いつかないなあ。
UN*X系のOSで別に正しく使えばファイルが消えちゃうとかはないでしょ?
0500nobodyさん
03/09/07 15:03ID:???0502nobodyさん
03/09/07 15:14ID:???0503496
03/09/07 19:04ID:???flockでデータベースを丸ごとロックするより、
他の方法を使ったほうが限界性能が上がると言いたかったのですが…。
別の話として。
>Windowsやover networkでうまく働かない以外に何か問題あったっけ?
ActivePerlの場合、WIN32APIのLockFileEXが使えれば、Windowsでも使えます。
そして、それはうまく働きます。
私はflock(2)の信頼性を否定しません。
とはいえ、perlのflockについてはperldocに例外事項が書かれています。
(498さんの言いたかったのはこれかな)
perlのflock関数 = flock(2)であるとは限りません。
参考:
perldoc -f flcok
perlソース pp_sync.c
ActivePerlソース win32.c
0504nobodyさん
03/09/07 22:04ID:???おいおい、何はぐらかしてんだ?
>Windowsやover networkでうまく働かない以外に何か問題あったっけ?
>他の方法を使ったほうが限界性能が上がると言いたかったのですが…。
他の方法とは?
0505nobodyさん
03/09/07 22:26ID:K46D6zau起動させればflockの信頼性が判るよ。いくつかはロックかからずに
スルーされるからさ。
後はロックの残骸による次プロセス(同一ロック)の停止かな。
遠回りしないと解決出来ないのは面倒。
漏れが間違っているかもしれんが、同時に数千〜数万単位でロックを
必要とする環境に置いて上記の理由からflockは使いたくないです。
よってほとんどDBのロックに任せっきり。DBだと単純なa=a+1の場合だと
DB自体が保証してるんでロック不必要だし。
間違っていたら本当にスマソ。業務でロックを故意に壊しにいった結果
こうなったので。
0506nobodyさん
03/09/07 22:35ID:???ソースとdfの結果みせてみな。
そういうケースの殆どはファイルシステムがNFSだった、って
オチな訳だが。
もし本当にflock(2)に信頼性がないなら、sendmailがmailboxファイルを消しまくる
現象が世界中で起きてるはずだが。
> 後はロックの残骸による次プロセス(同一ロック)の停止かな。
・・・は?
> 間違っていたら本当にスマソ。
多分間違ってると思う。
0507nobodyさん
03/09/07 23:19ID:???>いくつかはロックかからずにスルーされるからさ。
どうやって判断してんだ。テストコードがバグってんだろ。よくあることだ。
>ロックの残骸
って何?
>flockは使いたくないです。
>よってほとんどDBのロックに任せっきり
・・・
0508nobodyさん
03/09/07 23:54ID:???店に怒鳴り込む馬鹿親がいると聞きますが・・・。
この業界にも、道具を使いこなす努力をせずに、自分の無能を全部道具のせいにする
DQNが増えてきたってことですかね。
0509nobodyさん
03/09/08 10:14ID:???ハゲドウ
しかし、不良だらけの道具を平気で売ってる大企業とかも在るのが実情ではある。
M$とか。
0510496
03/09/08 13:21ID:???>>Windowsやover networkでうまく働かない以外に何か問題あったっけ?
perldoc -f flockから引用
>Calls flock(2), or an emulation of it, on FILEHANDLE. Returns
>true for success, false on failure. Produces a fatal error if
>used on a machine that doesn't implement flock(2), fcntl(2)
>locking, or lockf(3).
>On systems that support a real flock(), locks are inherited
>across fork() calls, whereas those that must resort to the more
>capricious fcntl() function lose the locks, making it harder to
>write servers.
というように、いい加減なfnctl(2)によりエミュレーションされた場合は
サーバーの書き込みが激しい場合ロックが失われると書いてあります。
>>他の方法を使ったほうが限界性能が上がると言いたかったのですが…。
>他の方法とは?
データベース側に専用のロック機構があれば、そちらにお任せしますが?
全部flockしますか?
0512nobodyさん
03/09/09 02:09ID:???んじゃ、perlにflock(2)の呼び出しが実装されてれば問題がないということでよろしい
でしょうか?
俺は思わず「fcntlがダメダメ -> POSIX準拠と呼べない -> UNIX系とも呼べない」
と思ってしまったが。
0513496
03/09/09 20:09ID:???flock(2)が機能して、正しく使えていれば問題ないかと。
私の知る限りでは、fcntl(2)でも十分信頼性はあると思いますけどね。
0514nobodyさん
03/09/12 14:11ID:e1VX9Ox6flock(2)はover networkじゃなく、正しく使えば基本的に堅牢。
Perlのflockはコンパイルされた環境依存、ってとこか。
fcntlでもちゃんとPOSIXに準拠してれば問題ないはず。
その腐ったfcntlを実装してるOSが何なのか知りたい。
Larryの事だから、誰も使わないようなかなりマイナーな物を
想定しているような気がするが。
しかしfcntlは堅牢でないからDBを使う、といってる人がいたが、
じゃぁそのDBはどうやってファイルをロックしてるんだろう?
0515nobodyさん
03/09/12 19:43ID:???と言い切ってみるテスト…。
0516nobodyさん
03/09/13 00:45ID:???0518nobodyさん
03/09/14 21:13ID:???PostgreSQLだったらセマフォ。
>>517
http://qmail.jp/mta/spool.htmlでも触れられているが、
NFSでlockdが腐る現象がまれに発生する事を実際に経験している。
(俺は信者じゃない)
0519518
03/09/14 21:24ID:???これ、やっぱ嘘かも。
しかし、排他制御のプリミティブはfcntlやflockだけではない。
0520nobodyさん
03/09/15 06:39ID:???0521nobodyさん
03/09/15 06:42ID:???0522nobodyさん
03/09/15 07:54ID:???0523nobodyさん
03/09/15 10:38ID:???0524nobodyさん
03/09/15 17:19ID:???結構でてくるのですが、どれかお勧めはありますか?
それとも毎回自分で処理を書いたほうがいいのでしょうか?
0525nobodyさん
03/09/15 18:11ID:???「flock は腐ってる。 DB 使え」という答えしか返ってこない。
0527nobodyさん
03/09/15 23:44ID:???そんなこと書いてるのは約一名だろ。
>>524
perl -MConfig -e 'print $Config{d_flock}."\n"'
これ実行して「define」と出ればflock(2)が実装されてるからまず大丈夫。
ネットワーク越しでなければラクダ本に書いてあるflockのサンプルで充分。
0528nobodyさん
03/09/16 00:04ID:???何人か見た事あるので充分なのかどうかは微妙とか言ってみるテスツ。
0529nobodyさん
03/09/16 01:04ID:???0530nobodyさん
03/09/16 02:04ID:???別にseekやってもオーバーヘッド以外の害はないんだし、害がある場合もレアケースながら
存在するので、的確かどうかはともかく、少なくとも「充分」ではあるのでは?
0531nobodyさん
03/09/27 12:58ID:???mkdirで新規ディレクトリを作ったうえで、ロック成立条件を満たした場合にロック完了とする。
ディレクトリ名にタイムアウト時刻と共有/排他ロックの種別を埋め込む。
共有ロック時はディレクトリ作成後に、親ディレクトリのファイルリストを取得して、
自分の作ったディレクトリよりも前に排他ロックディレクトリが作成されていなければ、ロック完了。
排他ロック時も同様に、自分の作ったディレクトリよりも前にディレクトリが作成されていなければ、ロック完了。
もちろん、ファイルリスト取得時にタイムアウト時刻を過ぎたディレクトリは消去する。
環境依存せずに、read-write lock patternをperlで実装するとこうなるね。
0532nobodyさん
03/09/29 13:16ID:???flockサポートしてない環境ってそんなに一杯あるんですか?
windows 9xでサーバ立てる香具師はほっといたとして、、、
nkfのlock機構って精度低いんですか?
0533nobodyさん
03/09/30 04:58ID:???nkf の lock 機構ってのは聞いたことないんだが、
・・・っていうか、一体いつまでおんなじような議論を堂々巡りで続ける気なんですか?!?!
0535532
03/09/30 11:52ID:???0539531
03/10/02 09:02ID:???やっぱうちのサイトですか(w
で、今改良版を作ってるのですが、タイムアウト時刻をディレクトリ名にすると、同時にタイムアウト時刻が
違うロックを作ると誤動作するな。
だから、現在時刻をディレクトリ名にして、ディレクトリの作成時刻をタイムアウト時刻に変更すると言う
アクロバティックな操作が必要かもね。
改良版出来上がったら公開しますか?(y/n)
0540nobodyさん
03/10/02 16:33ID:???自作CGIを評価するスレ
http://pc2.2ch.net/test/read.cgi/php/1049514428/470
何これ。恥ずかしがりやさんなのかな。
0542nobodyさん
03/10/03 18:38ID:???いやいや何か勘違いしてない?
ファイルロックの話なんだからこのスレでいいだろう。
俺の言いたかったのは>>539の最後に(y/n)があって、
何故かhttp://pc2.2ch.net/test/read.cgi/php/1049514428/470 で
yと答えてたので報告したまでです。
0543nobodyさん
03/10/03 18:51ID:???これって安全そうでよさげな気はするんだけど、
ちょっと思ったんだけど、ものすごくアクセス多い場合に、
ディレクトリ作成〜ファイルリスト検査のタイムラグのせいで、
いつまでたってもだれもロックを取得できない、ってな状況になりそうな気がする。
0544531
03/10/05 10:57ID:???今度の奴は、ロックする側のプロセスがタイムアウト時間を個別に設定できます。
http://do.sakura.ne.jp/~junkroom/cgi-bin/megabbs/lounge/index.html
>>543
確かにファイルリスト検査に時間がかかるが、ならばどうしろと?
0545nobodyさん
03/10/06 12:54ID:???いや、どうすればいいか私にも思い付きません。すいません。
単にデメリットを挙げてみただけで、
だからといってその方法が使えねーとかいう気も毛頭ありません。
0546531
03/10/06 22:56ID:???さらに一念発起してrename方式に変更してロック処理にかかる負荷を低減してみました。
rename方式でテストしたらロックがぶっ壊れるなー、とか思ってたら
ロック検証用のルーチンの書き方に問題があった罠。
同じファイルを読み込みと書き込みで2回オープンして、しかもバッファ処理をカットしてなかったので、
スクリプト上では書き込んだつもりでもファイルシステム上では「まだ」書き込まれてない場合があることに
ようやく気がついた。
教訓。
ロック処理が正しくても、ファイル入出力の部分の書き方によっては思わぬファイル破損がありうる。
0547531
03/10/07 18:17ID:???やっぱりread-write lockってむづかしいでつね。
rename方式だと、共有ロックをかけているプロセス数が分からないといつロック解除していいかわからない。
ロックプロセス数を安全に記録するために、内部で排他ロックをかけなければいけない罠w
これでどのくらいロック処理で負荷がかかるか、だな。
0548nobodyさん
03/10/29 05:07ID:???例えば掲示板で最初のページだけ静的なファイルにしたいという場合、
ログとその最初のページの両方を同時にロックしないといけないので。
FLOCKのディレクトリ版とかあれば便利なのですが…。
0549nobodyさん
03/10/29 06:01ID:???ロック開始と解除の間で必要なファイルを扱えばいいだけ
ロックの仕組みを根本的に理解していないんじゃないか?
もうちょっと勉強せい
0550nobodyさん
03/10/29 08:13ID:???http://pc2.2ch.net/test/read.cgi/php/1024795138/
0551nobodyさん
03/11/03 16:44ID:???ttp://www98.sakura.ne.jp/~jun/perl/flock.html#02
0552nobodyさん
03/11/05 02:38ID:???flockってロックしたファイルが閉じるまでに開いた他のファイルまで
全部ロックしちゃうの?
0555nobodyさん
03/11/05 14:16ID:???読んだけど。
かいつまんで書くと
lockfileを開く
lockfileをロック
count.txtを開く
上書き
count.txtを閉じる
addr.txtを開く
追記
addr.txtを閉じる
lockfileをアンロック
だよね。
count.txtとaddr.txtには直接ロックかけてなくて
lockfileをロックすることによりこの二つのファイルもロックされてるらしいから
>551みたいに言った。
0556nobodyさん
03/11/05 14:16ID:???0557nobodyさん
03/11/05 14:28ID:???よく考えたらlockfileがロックされてるときはそこから先に進まないから大丈夫なのか。
0558nobodyさん
03/11/08 02:04ID:???どっちかのファイルにロックかけて最後まで開いてるままで十分だけどな。
0560nobodyさん
03/11/08 13:37ID:???0562nobodyさん
03/11/08 17:35ID:???0563nobodyさん
03/11/09 03:10ID:???レアケースだろうけど
似たような事して壊れたことあるよ
無茶苦茶って事では無いだろうが、
そのやり方だと同時オープンで
2人アクセスしてきたのに1しかカウントアップしないって
ケースがタイミング良ければ発生する程度かな
0567nobodyさん
03/11/09 18:12ID:???単に読み込みをブロックしてなかっただけってオチなんじゃ。
それか二つのファイルでファイルハンドルを同じにしちゃったとか…。
>564
open(COUNT, "+<$cfile");
flock(COUNT, 2);
(中略)
open(ADDR, ">>$afile");
(中略)
close(ADDR);
couse(COUNT);
0568nobodyさん
03/11/09 18:18ID:???複数のスクリプトが複数の同じファイルを読み書きする場合は
ロック用ファイルを一つ用意する方が管理が楽なのは当たり前。
でもカウンターのようにファイルが単一のスクリプトからしか読み書きされない場合は
どちらか先に読む方のファイルをロックしておけば十分。
0570nobodyさん
03/11/09 18:58ID:???サーバがflockをきちんと使えないシステムを採用してたとかじゃないの?
0572nobodyさん
03/11/09 19:42ID:BVCYv2fe馴れ合いはよそでやれよ・・・
ま、>>555は書いてるとうりにすれば問題無し
わざわざ混乱させんでもよかろうに
0574nobodyさん
03/11/09 19:55ID:4SnYD/Cs|.本日選挙は20時迄!|
|__________|
∧∧ ||
( ゚д゚)|| <残り10分切ったど!
/ づ 投票してない香具師は自衛隊の代わりにイラク逝けよ。
※総務省によると、総選挙の中間投票状況は
9日午後4時現在、全国平均で40.04%。前回を1.40ポイント下回っている。
0575nobodyさん
03/11/09 19:59ID:???あれが自演ならお前さんも>>569か?って事になるじゃん…。
本当だったら煽った挙句自演呼ばわりですかって感じで笑えるけど。
0579564
03/11/10 14:47ID:???まぁどっちでもこの場合変わらないけど。
0582nobodyさん
03/11/10 16:19ID:???0583nobodyさん
03/11/10 16:43ID:???0584nobodyさん
03/11/10 16:56ID:???0585nobodyさん
03/11/10 20:26ID:???0587nobodyさん
03/11/10 20:37ID:???ユニークなファイル名を生成するようにしないと。
…今思ったけど、たいした事無いなw
0588蟻の子一匹通さないロック
03/11/14 04:40ID:uv5dJ3X620 処理;
30 逆転無罪; # 真犯人逮捕⇒釈放
0590nobodyさん
03/11/14 16:05ID:???つーか変わってくるとしたらあれだ・・・
掲示板とかのスクリプトで
LOG→HTML随時吐き出し型
じゃなく
LOG=HTMLを表示する型
の場合、Rename型の排他処理は行えない可能性がある。
ということで。
結論から言えば退避ファイル名をhtml→htmとか適当に変えればいいんだろうけど。
0591nobodyさん
03/11/14 17:52ID:???・flockが使えない環境ではどうしてる?
・ロックの有効性はその方法でなく、ロックを組み込む場所が大事。壊れる原因の大半は誤った使い方によるものなので、ありがちな落とし穴の再検証をしよう。
後者をよく理解してない初心者・中級者が、「flockで壊れた!flock使えねー」とわめいて、前者と後者をまぜこぜにして語って、スレが荒れるのが常。
0592nobodyさん
03/11/14 18:00ID:???0593nobodyさん
03/11/14 18:11ID:???どんな環境でも使えて、軽くて、頑丈なロックを考えようじゃありません
0595nobodyさん
03/11/14 18:38ID:???0598nobodyさん
03/11/16 17:30ID:???やってくれるやん・・・・・・・・ってのはだめなの?
あくまでOSにLockさせないとあかん?
0599nobodyさん
03/11/16 17:34ID:???0601nobodyさん
03/11/17 02:04ID:???空気よめなかった。すまそ。
0604nobodyさん
03/11/18 17:29ID:???俺が見た事ないだけかもしれないが
0605nobodyさん
03/11/18 22:15ID:???個人サイトならカウンタCGIを置くだけでしょ。壊れても問題ないし。
どしてもというなら、セマフォ管理するプロセスを立ち上げといて
それ使うって手もあるのかもしれんがそれならDB使うよ。
OSのファイルロックはアトミックじゃないっす。ソラリスでもそう。
マルチアクセス前提のファイルシステムもあるが、民生用じゃないな。
0606nobodyさん
03/11/21 00:36ID:???大規模サイトが、アクセスカウンターで解析するか?
ふつー、Webサーバのアクセスログを解析するだろ。
> OSのファイルロックはアトミックじゃないっす。ソラリスでもそう。
お前の使い方がヘボなだけ。
0608nobodyさん
03/11/21 01:56ID:???確かに大規模サイトにはカウンタはないな。でもユーザーごとにレスポンスを
細かく制御すると、リアルタイムなユーザー管理いるからどうしてもDB。
ログ解析だけだとマーケティングデータしか出てこない。インタラクティブ
リアルタイムにそれ使わないと意味なしな。
静的なサイトでページビューだけでいいならログだけでいいけど、それじゃ
このスレの話題ずれる。
ちなみに俺はDB使わない程度のサイトならservletでロック処理。
0609nobodyさん
03/11/21 02:13ID:???スレタイを何度も声を出してよく読んでから発言した方が良いのでは?
どう考えてもあなたのレスはどれもこのスレにはお呼びでないと思うのですが?
0610nobodyさん
03/11/21 02:23ID:???このスレには、人のことを「ヘボ」としか言わないやつがいて
それがどうもしゃくに障ったんでな。Perlの話しなくてスマソ。
0611nobodyさん
03/11/22 00:21ID:???Webアプリなら自前でログ持つ、バグ対応すること考えれば当たり前。
「ソラリス」なんて呼ぶ奴が「OSのファイルロックはアトミックじゃないっす」といった時は
使い方間違ってる確率99.9999%
0612nobodyさん
03/11/23 05:00ID:???0614nobodyさん
03/11/23 05:41ID:???単純に思いつくのはキューですが・・・
やっぱデーモンみたいな別プロセスに一括一元管理させるのが安全っちゃ安全ですよね?
0615nobodyさん
03/12/04 07:40ID:???結局、実用に耐えるファイルロックはどれなのか
スクリプト例でまとめて欲しい。おねがいエロイヒト。
0617nobodyさん
03/12/13 19:02ID:???0618nobodyさん
03/12/13 19:54ID:???0619nobodyさん
03/12/15 12:22ID:???ファイルロックなんだかDBロックなんだかわからんような
あやしげなロックが提供されるんじゃないのか
0620nobodyさん
03/12/15 19:16ID:???排他処理中はキーが書き込まれます。
0621nobodyさん
03/12/19 21:19ID:???ってこと無いですか?
0622nobodyさん
03/12/19 23:28ID:???あぁ、知識が足りなくて自分は使えないと?
やっぱりありませんね
0623nobodyさん
03/12/20 02:36ID:???if(!flock($fp, LOCK_EX)) { fclose($fp); echo "ns"; }
echo "ok";
これでいい?
0624nobodyさん
03/12/20 02:38ID:???つーかヘルプに書いてあった。
0625nobodyさん
03/12/21 05:04ID:FyNOPbG50626nobodyさん
03/12/21 16:43ID:???0627nobodyさん
04/01/08 00:54ID:???多分既出の話。
0628nobodyさん
04/01/18 18:15ID:???ブックマークから外してしまおうかな。。
0629nobodyさん
04/01/18 19:34ID:???0630nobodyさん
04/01/18 20:27ID:???いままでありがとう。
0631nobodyさん
04/01/19 01:52ID:???0632nobodyさん
04/03/11 20:28ID:???ネタが尽きたところで脱線したいんですが、
includeしたりするファイルはflockの必要が無いことを前提としているんですかね。
書き換えや追記などを行うファイルに対し、
includeやrequireしたりするのはナンセンスということで合ってますか?
0633nobodyさん
04/03/12 15:23ID:???実行するperlスクリプト本体にflockの必要があるか、という話と同じなんじゃないかと
0634nobodyさん
04/03/12 15:32ID:???0635nobodyさん
04/03/12 23:11ID:???PHPにおけるincludeやrequireは単にプログラムの記述されたファイルだけでなく、
HTML、PHP複合型やtxtまで読み込めるわけです。
そういった意味での質問です。
0637nobodyさん
04/03/15 12:04ID:???php でも perl SSI でも何でもいいんだけど、ロックが重要になるのは基本的に、
ファイルを書き換えるプロセスが複数存在して競合する場合、つまり
A:----->読み込み------->処理-------->書き出し---------------------
B:------------------->読み込み------->処理-------->書き出し-------
のようなケースね。
ロックしないとマジでファイルが壊れたり情報が失われたりする。
これに対して include や require って、
読み込みオンリーで書き換えが有り得ないという前提なので、
上記のような書き込みの競合に参加しないわけで、
そういう意味ではロックの必要性が薄い。
(全く必要性が無いわけじゃないが、ほとんどの場合無視できる)
0638nobodyさん
04/03/15 16:15ID:???厳密に言えばロックの必要性があることを示しているんですよね。
0639nobodyさん
04/03/15 16:44ID:???0640nobodyさん
04/03/15 16:44ID:???0641nobodyさん
04/03/15 18:08ID:???sh ってスクリプトを一行読み込んで実行してを繰り返すから、
実行途中にスクリプトを書き換えると結構悲惨なことになったりするよな。
0642nobodyさん
04/03/17 13:37ID:???どうもOSによっては、ファイルシステムの情報取得にタイムラグがあるようで、
renameかけても、OSが保持するファイル情報が即座に更新されないために、
同じ元ファイル名からのrenameが成功してしまうことがありました。
より正確にrename形式でファイルロックをかけるには、
rename後に若干のタイムラグを置いて、rename後のファイルの存在チェックが通れば
ロック成功と考えた方がいいですね。
ちなみに、WinXP+NTFSの組み合わせでそれらの現象がありました。
Linuxだったりすると、こういう現象は出てきますでしょうか?
0643nobodyさん
04/03/17 16:25ID:???何か間違っている。
0646nobodyさん
04/03/19 13:53ID:???仕方なく-dや-eをしなさい。
0647642
04/03/19 16:28ID:???その辺(ファイル操作後の存在チェック)は仕方なく実装してます。
同一プロセスで、同じファイルからのrenameコマンドを連続して実行すると、2回目は失敗(これが通常動作)するので、
他プロセスでのファイル操作の結果が反映されるのが遅いらしい。
0648nobodyさん
04/03/19 16:33ID:???0649nobodyさん
04/03/29 10:00ID:WLF8C9h8ログにはきちんと20万行書かれてた。
for ($i = 0; $i < 10000; $i++) {
open (DATA, ">>$file");
flock (DATA, 2);
print DATA $str;
close DATA;
}
こういうのじゃ、そのOSでflockが使用可能かって言う確認にはならないのですか?
ちなみに、環境はWin2KとActivePerl5.6.1で試しましたが。
0650nobodyさん
04/03/29 17:51ID:???そもそも flock が使用不能なら呼び出した時点で実装されてないって怒られます。
実用的に使用可能か、という意味なら実際に試してみる価値があるかもしれません。
ただし、自分の想定している条件に近くないとあまり意味がないと思います。
0651nobodyさん
04/03/31 01:14ID:???perlで壊れないロックはflock()だけだった。
0652nobodyさん
04/03/31 05:45ID:???0653nobodyさん
04/03/31 07:07ID:???どんなんだろう。
0654nobodyさん
04/03/31 12:43ID:???0656nobodyさん
04/03/31 13:50ID:???ロックに失敗してると考えると納得できる話だな > 2chがchmodでロック
0658nobodyさん
04/03/31 18:13ID:???0660nobodyさん
04/03/31 23:37ID:???どうせアトミックじゃないのなら
1000の書き込み後にchmodして
1001はクライアントで描画
dat落ち時にはdatに1001を書く、
とか適当にやれば1030くらいで止まるんじゃない?
ダサいけど。
0661nobodyさん
04/04/10 18:40ID:???運用の奴ら全員で1台のディスプレイを囲んで。
オンラインでの議論なんて無駄無駄。
0662nobodyさん
04/04/16 01:00ID:???0663nobodyさん
04/04/19 09:45ID:???ロックファイルをファイルロックしなければならなくなった。orz
0664nobodyさん
04/04/21 07:50ID:???0665nobodyさん
04/04/21 12:24ID:???よくある流行歌の「君がいるだけで」というフレーズが言い当てています。
0666nobodyさん
04/04/23 14:39ID:???0667nobodyさん
04/04/26 01:30ID:???0668nobodyさん
04/04/26 01:31ID:???0669nobodyさん
04/04/27 11:45ID:???1分でレスしてきた君のためにGTO神書き換えのレスで返そうかと思ったけど、難しいのでやめた。
例えば、/path/to/dataというパスのファイルをファイルロック中は/path/to/data.lockとするぷろぐらみゅがあるとして、
その横で
while(1) {
open(F, '>/path/to/data');
close(F);
open(F, '>/path/to/data.lock');
close(F);
}
なんてことされたらたまんねぇと。
まあ、適切にパーミッションを設定すれば問題ないのだが、
私はファイルは0666、ディレクトリは0777でも問題ないことを信条としてるのであれかなと。
0670nobodyさん
04/04/27 13:29ID:???それは、前提が間違ってると思う。
「みなさん、ロックのためのリソースの○○はこうこうこういうふうに使いましょう」
っていう規約をみんながきちんと守ってる、っていう前提で設計しないと。
そんなこと言ったら、「ハカーが○○してきたら」とか「電源落されたら」とか
「スーパーユーザに○○されたら」とか考え出したら何もできないと思う。
0671nobodyさん
04/04/27 13:54ID:???ハァ?お前は K E N T か?
アップローダーを例に取るとサーバーとユーザーの設定次第で
http://pc5.2ch.net/test/read.cgi/hp/1076940865/888n
のような事も起こってしまうわけで。
専用のサーバーを使うなら>>670のような設計で構わないと思うけど、
こっちは共用向け、大量配布だからな。そういうわけにはいかんのよ。
0672nobodyさん
04/04/27 14:22ID:???「 K E N T 」というのは何だか知らないけど、そういうことなら納得です。
# でも >>667 のようなレスからそんな事情は推し測れないよ。
0673nobodyさん
04/04/27 17:59ID:???初回起動時にランダムな文字列のディレクトリ名やファイル名をスクリプトが自分自身の中に保存して、
それを使い rename()(または mkdir() や open() で作成)してそれをベースとするとか。
ディレクトリ内の一覧表示とかに弱いし総当りもあるし完璧では無いけど。
0674nobodyさん
04/04/27 18:00ID:???なんてこったい。
0675nobodyさん
04/04/27 20:43ID:???0676nobodyさん
04/04/28 01:00ID:???0678nobodyさん
04/04/28 01:51ID:???0679nobodyさん
04/04/28 02:52ID:???話を始めるようにしようよ。
でないと議論にならないし不毛すぎるよ。
>>667 みたいな話の切り出し方は最低。
0680nobodyさん
04/04/28 16:51ID:???0681nobodyさん
04/04/28 17:14ID:???0682nobodyさん
04/04/30 17:27ID:???そんな物を使うぐらいならソケットでプロセス間通信をしてしまう方が楽であると思うが、
Perlなんかでそんな事したらパフォーマンスが(以下略
0683nobodyさん
04/05/19 04:13ID:???誰かがファイルオープンしているときに別プロセスからファイルを読みこもうとした場合openエラーになっちゃいますよね。
それが嫌な場合は
open(DATA,"< test.txt");
flock(DATA,1);
なんたらかんたら
close(DATA);
みたいにして一人がオープンしている間は別プロセスには待たせればよろしいんでしょうか?
flockの説明を見てみると読みこみだけの時用の番号がなかったので、不安です。自分のPCはwin98なのでflockは使えませんし、
鯖にぶつけ本番はいやだなと思って聞きにきました。
0685nobodyさん
04/05/19 07:03ID:???書き込みの処理が2つ以上同時に行われないと分かっている場合
かつ、一過性の読み込み失敗を許容する場合
書き込みにロックは不要ですか?
0686nobodyさん
04/05/19 09:38ID:4B5lUTgr話はそれからだ
0688683
04/05/19 17:00ID:???いらないんですか。ということはアクセス集中によるオープンエラーは読みこみだけならば
起こらないということですか?
本当は自分でその状況を作り出してテストしてみたいんですけど、動作テストはwin98に入れたhttpdなので
同時アクセスが試せないんですよね。
ファイルオープンするCGIがユーザに色んな項目を記入してもらった次のページなのでエラーが
でちゃうとまた、入力してもらう事になってしまうのでそれはまずいなと思いまして;
0689nobodyさん
04/05/19 18:15ID:???これがそもそも勘違いだしな。
0690nobodyさん
04/05/19 19:43ID:???Windows はどうだか知らんけど、
UNIX なら読み出すだけならアクセス集中でオープンエラーなんてないだろ。
つーか、そこまで信頼性高いシステムが必要なら、2ちゃんなんかで質問するより、
もっとちゃんと調べて勉強するか、外注に出した方が良いんじゃないか?
0691683
04/05/19 23:00ID:???ありがとうございます。
吐いた制御ってオープンエラーを防ぐんじゃなくて、書きこみが同時に行われてファイルが壊れるのを
防ぐためにあるってことですね。
>>690
ありがとうございました。
0692685
04/05/20 15:35ID:???返答ありがとうございます。
>>686
Dirty readとは書き込み中に読み込めるということで、最新でないものを読み込めてしまうということでしょうか。
それは構いませんし、リロードで直る一時的なものであれば読み取りが0バイトでも構いません。
>>687
そういう事になるかも知れません。
言い換えると
書き込み処理が重複しない時、理論的にファイルが壊れるか否かが知りたいのです。
0693nobodyさん
04/05/20 20:28ID:???その中でも「書き込み処理が重複する」という原因はよく起こる。
この重複を避けるための道具が、ファイルロック。
ロックは、これさえかければファイルが壊れなくなるという魔法の杖ではない。
ロックは単なるプログラミングの道具に過ぎず、
それも、ファイルを壊さなくするための道具ではなく、
書き込みが重複しているかどうかを識別するだけの道具。
識別した上で書き込みが重複しないようにプログラムを書くのは、プログラマの責任。
逆に、書き込みが重複しないということが100%保証されているなら、
ロックをかけてもかけなくても変わらない。
もちろんその場合でも、書き込み処理重複以外の原因でファイルが壊れることは、いくらでも考えられる。
0694nobodyさん
04/05/20 20:38ID:???保証する方法なんてあるのか?
0695nobodyさん
04/05/20 21:07ID:???まではいい事言ってると思うんだが最後の方になって壊れてるな。
0696nobodyさん
04/05/20 22:40ID:???単に、書き込みが100%重複しない論理空間を仮定すれば、というだけの話でしょ。
もちろん現実にそんなことはありえないと暗示しているわけで。
0697685
04/05/21 01:02ID:???>>693
という事は書き込みが重複しないなら、
ファイルロックで防げる程度のトラブルは防げるという事ですね。
>>694
書き込み処理を行えるのがパスワードを知っている1人なのです。
パスワードが他人に漏れず、その1人が同時に操作せず、
openしたまま処理が中断することもない・・・
という仮定はありますが。
ファルイロックの基本的な知識さえない私に丁寧な回答ありがとうございました。
0698nobodyさん
04/05/27 13:48ID:???けっこうウソ書いてあるサイトが多いのに驚いた。
0700nobodyさん
04/05/27 20:14ID:???0701nobodyさん
04/05/27 21:10ID:???0702nobodyさん
04/05/27 21:08ID:???0703nobodyさん
04/05/28 01:38ID:???見せてよ
0704698
04/05/28 11:16ID:???自分で掴み取れ! これに尽きるな
0705nobodyさん
04/05/28 15:29ID:???0706nobodyさん
04/05/30 14:43ID:???0708nobodyさん
04/05/30 18:12ID:???0709nobodyさん
04/05/30 22:14ID:???を使う。速いしいいぞ。
0710709
04/05/30 22:16ID:???xs使って作るしか、、、。
0711nobodyさん
04/05/30 22:23ID:???http://search.cpan.org/~gsar/libwin32-0.191/
0712nobodyさん
04/05/31 00:08ID:???他のOSとかもないのかな。
lock::mutexとかいう一本にまとめて使えるようなライブラリがいいなぁ。
mutexもセマフォも使えないけどflockは使えるOSだったら、
内部実装はflockでやるとか。
0713357
04/05/31 20:57ID:???0714713
04/05/31 22:53ID:???0715nobodyさん
04/10/09 22:28:45ID:???タアソウスルナラ イマノウチ
0716nobodyさん
04/10/09 23:12:22ID:???flock(LOCK,2);
open (IN, "count.dat");
$count=<IN>;
close(IN);
$count=$count++;
open (OUT, ">count.tmp");
print OUT $count;
close(OUT);
rename("count.tmp","count.dat");
unlink("lock.tmp");
flock(LOCK,8);
close(LOCK);
これでOK?
0717nobodyさん
04/10/10 04:46:13ID:???$count=$count++;
は
$count++;
でいいと思うけど。
0720nobodyさん
04/10/10 17:10:11ID:???open (IN, "count.dat");
flock(IN,2);
$count=<IN>;
$count++;
print IN $count;
close(IN);
これでいいじゃん
0721716
04/10/10 17:16:22ID:???0722nobodyさん
04/10/10 17:19:40ID:???open (IN, "+>count.dat");
0723716
04/10/10 17:36:23ID:???0724nobodyさん
04/10/10 17:43:35ID:???そんなのは一概には言えない。
各ファイルは読み込み・書き込み・両方のいずれなのか、
一度に連続して読み書きするのかなど。
0725nobodyさん
04/10/20 14:16:48ID:ejI/DpjA0726nobodyさん
04/10/21 19:09:46ID:wxBAgdgRmkdirとかにしといた方が無難かね?
それぞれでflock()したって排他かからない?
0727nobodyさん
04/10/21 19:24:18ID:???0728nobodyさん
04/10/21 23:27:35ID:???デマ飛ばすな。ボケッ
man perlfunc
flock FILEHANDLE,OPERATION
Calls flock(2), or an emulation of it, on FILEHANDLE.Returns true for success,
false on failure. Produces a fatal error if used on a machine that doesn't implement
flock(2), fcntl(2) locking, or lockf(3). flock is Perl's portable file locking interface,
although it locks only entire files, not records.
0729nobodyさん
04/10/22 01:27:00ID:W+TTmfbFなるほど、結局perl,phpのflock()が同じシステムコールを使うかどうかって所ですかね?
linux(redhat)なんですが、普通にflock(2)使ってると思って良いのかなぁ。
0730nobodyさん
04/10/22 17:20:32ID:???0731nobodyさん
04/10/23 01:59:39ID:???php4.3.9/linux はソース確認したところ flock(2) 使ってないよ。fcntl(2)。
0732nobodyさん
04/10/23 02:53:34ID:???0733nobodyさん
04/10/23 04:34:45ID:???双方とも flock(2) が使える環境では flock が使われる.
また間違ってるかも知れないので、調べたソースを書いておく。
php-4.3.9 ./ext/standard/flock_compat.c
perl-5.8.5 ./pp_sys.c
0734nobodyさん
04/10/23 13:22:56ID:???flock(2)使える環境って前提になるが(BSD,SystemV,Linux?)、PerlでもPHPでもflock()でいけるのか。
NFS上のディスクは別として。
0735nobodyさん
04/10/25 18:24:04ID:???0736nobodyさん
04/10/25 19:07:12ID:???0737nobodyさん
04/11/06 19:49:00ID:em3fuQlS0738nobodyさん
04/11/06 19:58:00ID:???0739nobodyさん
04/11/07 05:49:26ID:???0740nobodyさん
04/11/07 23:08:21ID:???0744nobodyさん
04/11/08 13:12:26ID:BIj8xOyZ「一度捕まえたら、離さない・・・・・」
TAITOの名作シューティングRAY・FORCEができるのは
セガサターンだけ!
0745740
04/11/08 21:24:24ID:???0746nobodyさん
04/11/08 23:46:08ID:???0749nobodyさん
04/11/09 08:59:34ID:???0750nobodyさん
04/11/09 13:16:33ID:???0751nobodyさん
04/11/09 13:43:34ID:???0752nobodyさん
04/11/09 20:07:15ID:???NFSを使った事無いので、良く分からないので教えてください。
NFSを利用する時はflock関数にflock(2)ではなくfcntl(2)を利用するように
perlをビルドすると思いますが、それでもロックは壊れるのでしょうか。
fcntl(2)で壊れる場合、実際の解決手段として、どのようなものがあるのでしょうか。
0755nobodyさん
04/11/10 21:25:46ID:???それは、ロック機構が無くても信頼できるメールボックスの話だと思うのですが、
一般的なファイルアクセスにも使えるのでしょうか。
0756nobodyさん
04/11/12 07:07:11ID:djvAfFkIレイフォース >>>> 越えられない壁 >>>> レイヤーセクション
0757752
04/11/13 13:06:05ID:???・NFS Version4なら、ロック機構が組み込まれているので問題が無い(flock(2)でok?)
・NLM(Network Lock Manager)プロトコルに対応したサーバとクライアントならば、
fcntl(2)で対応可能。(ただし、一部のシステムで信頼が無いかも)
・それ以外はロックファイルを作るのが一般的
という感じらしいことが分かりました。
ありがとうございました。
0758nobodyさん
04/11/13 15:51:42ID:6imth/Ieレイストーム >>> レイフォース >>> レイクライシス
0759nobodyさん
04/11/14 12:08:06ID:???0760nobodyさん
04/11/15 01:32:31ID:???0761nobodyさん
04/11/18 09:27:07ID:upfr9/eiそれなに?
0762nobodyさん
04/11/18 10:10:24ID:3NzX+MnA懐かしい
0763nobodyさん
04/11/18 19:52:46ID:GLzLqJbZ0764nobodyさん
04/11/18 20:49:35ID:???0765nobodyさん
04/11/27 15:36:14ID:o5xdYnQz0766nobodyさん
04/11/27 15:54:59ID:???0769nobodyさん
04/12/04 19:37:01ID:???0770nobodyさん
04/12/20 07:41:20ID:???壊れてる可能性のあるところってバッティングしているときのだけでしょ?
0771nobodyさん
04/12/20 14:13:21ID:sskqg6P0現在1つのスクリプト中に複数の箇所でファイルロックを使ってます。
これらのファイルロックを全てやめて代わりに、
スクリプトの一番最初でダミーのファイルにロックをかけて
スクリプトの一番最後でロックを解除するようにして他のプロセスが
スクリプトを実行しているときはスクリプトの実行自体を順番待ちさせて
同時に複数のプロセスがファイルへの書き込みをできないように
変えようと思いますが、何か問題あるでしょうか?
1つ気になるのは、もしスクリプトの途中でexit関数等でスクリプトの実行が終了した場合は
自動的にダミーファイルのロックが解除されファイルも自動的にcloseされますか?
0773nobodyさん
04/12/20 15:30:20ID:???プロセスが死ねばロックは解除される。
先頭と末尾でロックと解除をするようにするのはいいが、
パフォーマンス低下は明らか。
0774nobodyさん
04/12/20 16:09:04ID:???スクリプトの実行が終了してもプロセスは死なないと思うけど
mod_* がスクリプト中の flock の後始末を面倒見てくれるんですよね?
0775nobodyさん
04/12/20 20:09:18ID:???二つ以上のプロセスが同時に追記したら、データが混じる可能性があるし。
>>772
勧告ロックはそうはいかない。
>>774
PHPは面倒みてくれるけど、mod_perlのファイルハンドルは無理。
だから、IO::File,FileHandleモジュールなどを使う。
http://perl.apache.org/docs/1.0/guide/porting.html#Filehandlers_and_locks_leakages
0776770
04/12/20 21:19:18ID:???ロックしなくて読んでいいのは、追記モードのときだけではないの?
上書きモードだと一旦中身が空になるわけで、そのときロックしないで
読んでしまったらだめだよね?
読み込んで、それをそのまま出力しておしまいな 2ch の read.cgi
みたいなやつならそういうアプローチもいいだろうけど、読んだデータ
を処理に利用する場合はだめと思う。
>>775
>>770 のやつ 「書込時にちゃんとロックする前提で」っていうのが抜けてた。スマソ
0777771
04/12/20 21:25:49ID:sskqg6P0回答ありがとうございます。
やっぱパフォーマンスの問題になりますか…
0780nobodyさん
04/12/20 23:16:39ID:???>>779
そだね
けちろん: 読み込みデータがハンパでもいいタイプのシステムなら
ロックは無用。読み込みデータがその後のデータに関わってくるのなら
ロック白
0781nobodyさん
04/12/20 23:47:40ID:???ロックの掛け方による
>>779
例えば固定長なら書込み途中のデータを見分けて使わない機構とかできそうな予感がするな?
>>780
そのけつろんは読みの場合限定ってことで
0783
05/02/02 14:16:34ID:hfbAK0ph0784nobodyさん
05/02/26 07:20:55ID:???0785nobodyさん
2005/03/27(日) 21:58:07ID:frr01O3q0786nobodyさん
2005/03/28(月) 02:50:20ID:QWQNdIylもちろん無料で( ̄ε ̄@)」
http://lock.service.jp/lock.cgi&user=xxx?id=1?timeout=60
http://lock.service.jp/status.cgi&user=xxx?id=1
# <html><body>OK</body></html>
# <html><body>NG</body></html>
http://lock.service.jp/unlock.cgi&user=xxx?id=1
こんな奴
0788nobodyさん
2005/03/28(月) 03:50:52ID:???0789nobodyさん
2005/03/30(水) 16:45:20ID:0SN1W7SJflock(FH, 2);
flock(FH2, 2);
0791nobodyさん
2005/03/30(水) 18:55:15ID:???Subject: Lock
user=xxxx
pass=xxxx
timeout=60
lock-id=1
==========
Subject: Unlock
==========
Subject: Status
こんな感じのメールでロック状態を管理してくれるサービスきぼんw
0792nobodyさん
2005/03/30(水) 19:01:47ID:???0793nobodyさん
2005/03/31(木) 04:46:07ID:???それだ!
To: lock@xxxx.xx.xx
Subject: Lock
user=xxxx
pass=xxxx
timeout=60
lock-id=1
=======
↓
登録してある住所にlock-id確認コードを郵送
↓
登録ページからlock-id確認コードを入力
0795nobodyさん
2005/04/02(土) 05:31:48ID:???perl $0.tmp
rename $0.tmp $0
0796nobodyさん
2005/04/04(月) 15:59:12ID:UmDaQFM/すげw
0798nobodyさん
2005/04/08(金) 19:48:39ID:???0799nobodyさん
2005/04/08(金) 21:23:04ID:???0800nobodyさん
2005/04/08(金) 23:18:53ID:???0802nobodyさん
2005/06/06(月) 21:34:45ID:nLjgLi0Tfor ($i = 0; $i < 10; $i++) {#10回繰り返す
return if link($0, $lock);#link関数でロックファイルが作成できれば終了
sleep(1);#作れない場合は1秒スリープしてから再挑戦
}
print "BUSY";#10回以内にロックできない場合はBUSYと表示
exit;#スクリプト終了
}
↑だとうまくいくのに、↓だとうまくいかないのは何ででしょうか?
↓ですとsleepを5回繰り返した後&error("BUSY")の処理をします。
sub create_lock {
local($retry) = 5;
# 1分以上古いロックは削除する
if (-e $lockfile) {
local($mtime) = (stat($lockfile))[9];
if ($mtime < time - 60) {
&unlock;
}
}
while (!mkdir($lockfile, 0755)) {
if (--$retry <= 0) {
&error("BUSY");#5回以内にロックできない場合はBUSYと表示
}
sleep(1);
}
exit;
}
0803nobodyさん
2005/06/06(月) 21:38:25ID:???0804nobodyさん
2005/06/06(月) 23:11:37ID:pBVz6jtYよくわからんがmkdirに成功するとwhileループを抜けてすぐ
exitするからじゃないか?
それ以外にも古いロックを削除するあたりが突っ込みどころ
ありそうだが、サブルーチンunlockがどういうものか示されて
ない以上は疑惑レベルだな。
0805nobodyさん
2005/06/07(火) 11:44:43ID:Jzx4SwvBフォルダを作って消してるだけのような気がするんですけど。
↓
&createlock();#mkdirでロックファイルを作成する
open(FILE,"+<$logfile");
〜(処理)〜
close(FILE);
&unlock;#rmdirでロックファイルを削除する
0806nobodyさん
2005/06/07(火) 12:33:20ID:???0807nobodyさん
2005/06/07(火) 15:11:06ID:???WEBに転がってませんかね?
環境 A B C
flock × ○ ○
mkdir ○ ○ ○
こんな感じの一覧表みたいなのがあればいいな
0808nobodyさん
2005/06/07(火) 18:06:21ID:???802です。お答えありがとうございました。
ごめんなさい、勘違いしてました。ちゃんとロックできました。
ところで、質問ですけども、
sub create_lock {
local($retry) = 5;
if (-e $lockfile) {
local($mtime) = (stat($lockfile))[9]; # ←この部分の[9]
if ($mtime < time - 60) {
&unlock;
}
}
while (!mkdir($lockfile, 0755)) {
if (--$retry <= 0) {
&error("BUSY");
}
sleep(1);
}
exit;
}
↑の文章の
local($mtime) = (stat($lockfile))[9];
特に[9]の意味が分からないのですが、この文章は何を意味するのでしょうか?
0809nobodyさん
2005/06/07(火) 19:19:30ID:???statはファイルの様々な情報を長いリストにして返す関数で、その9番目の
要素であるところのファイル更新時間だけ欲しいから[9]で取り出してると
いうことだな。詳しくはperldoc -f statでもしてくれ。
0811nobodyさん
2005/06/07(火) 20:15:05ID:???前から疑問に思っていたんだが、
> 9番目
0から始まっているから、この場合10番目なのはみんな知っていると思うけど、9番目といってもいいのかな?
どういう言い方が正しいのか教えて。
0812nobodyさん
2005/06/07(火) 20:59:09ID:???9番の要素、0番の要素の方がすっきりする?
0813nobodyさん
2005/06/07(火) 22:14:04ID:???my_flockのサブルーチンの中で、戻り値を「\%lfh」のようにリファレンスで返す理由がわかりません。どなたか教えてください
$lfh = my_flock() or die 'Busy!';
open(FILE,"+<$logfile");
chop($count = <FILE>);
$count++;
seek(FILE,0,0);
print FILE "$count\n";
close(FILE);
my_funlock($lfh);
sub my_flock {
my %lfh = (dir => './lockdir/', basename => 'lockfile', timeout => 60, trytime => 5, @_);
$lfh{path} = $lfh{dir} . $lfh{basename};
for (my $i = 0; $i < $lfh{trytime}; $i++, sleep 1) {
return \%lfh if (rename($lfh{path}, $lfh{current} = $lfh{path} . time));
} # ■↑戻り値がなぜ\%lfh?
opendir(LOCKDIR, $lfh{dir});
my @filelist = readdir(LOCKDIR);
closedir(LOCKDIR);
foreach (@filelist) {
if (/^$lfh{basename}(\d+)/) {
return \%lfh if (time - $1 > $lfh{timeout} and rename($lfh{dir} . $_, $lfh{current} = $lfh{path} . time));
last; # ■↑戻り値がなぜ\%lfh?
}
}
undef;
}
sub my_funlock {
rename($_[0]->{current}, $_[0]->{path});
}
0814nobodyさん
2005/06/07(火) 22:35:39ID:???ので、この作者は(他にもいろいろ方法は考えられるがたまたま)
その2つの値が入ったハッシュのリファレンスを返すという方法
を選択した、というところだろうか。
0815nobodyさん
2005/06/08(水) 00:31:21ID:HPDd28CP戻り値無しで
if (rename($lfh{path}, $lfh{current} = $lfh{path} . time));
return;
とやっても同じ
0816nobodyさん
2005/06/08(水) 12:02:28ID:???http://www.eucaly.net/
http://www.eucaly.net/
http://www.eucaly.net/
http://www.eucaly.net/
http://www.eucaly.net/
http://www.eucaly.net/
http://www.eucaly.net/
http://www.eucaly.net/
http://www.eucaly.net/
http://www.eucaly.net/
0818nobodyさん
2005/06/08(水) 13:04:42ID:???お答えありがとうございました。
何かの弾みで「./lockdir/lockfile」の名前が変わってしまうことってありますか?
その場合ってエラーを返すしかないのでしょうか?
0819nobodyさん
2005/07/02(土) 23:42:28ID:MoVRWRYGfile()を使ってたんですが、これはロックされてないですよね?
fopenしてflockに変更した方がいいですか?
0821nobodyさん
2005/07/06(水) 15:38:22ID:???0822nobodyさん
2005/07/06(水) 20:01:43ID:???0823nobodyさん
2005/07/07(木) 11:51:39ID:???0824nobodyさん
2005/07/11(月) 12:06:06ID:LOhIsGf7flock LOCK, 2;
処理;
↑のようにLOCKをしっぱなしで、closeをしないとどうなりますか?
一連の処理が終了したら、LOCKは自動解除されるんでしょうか?
0825nobodyさん
2005/07/11(月) 15:42:12ID:???0826nobodyさん
2005/07/11(月) 16:23:12ID:???0827nobodyさん
2005/09/29(木) 15:27:47ID:6eWvRT5Dによる可能性はありますか?
0828nobodyさん
2005/09/30(金) 17:50:44ID:???↓
ロックファイル1に時刻がなかったらロック用ファイル2を開いてロック(あったら待機)
↓
一時ファイルに書き込み
↓
読み込み用ファイルに内容をコピー
↓
ロック用ファイル2を閉じる
↓
ロック用ファイル1を空にする
最強、破損なし。
時刻は異常があった時に現在時刻と比較して無限待機させない用。
0830nobodyさん
2005/09/30(金) 21:17:53ID:???0831nobodyさん
2005/09/30(金) 21:28:52ID:???本質的には目新しいアイディアがひとつも無いどころか
単に無駄なことしてるだけに思えるのは気のせいですかそうですか。
0832nobodyさん
NGNGはなしにならんな。 あきれたよ。もう実家に帰る!
0833nobodyさん
2005/12/08(木) 21:09:42ID:pHM0ErCMついて自分なりに色々と試行錯誤した結果、以下の
ようなルーチンを作りました。
flockが使える事が前提ですが、何か欠点や改良点が
あれば指摘して頂けるとありがたいです。
filelock.pl
package filelock;
our %_lock;
sub END {
foreach my $file ( keys %_lock ) {
close( $_lock{$file}{'handle'} );
unlink( $_lock{$file}{'name'} );
if( $_lock{$file}{'tmp'} ) { rename( $_lock{$file}{'tmp'}, $file ); }
} }
sub readOpen {
my ( $file ) = @_;
my ( $handle );
_append( $file );
if( !open( $handle, "<$file" )) { return undef; }
return $handle;
}
0834nobodyさん
2005/12/08(木) 21:10:10ID:pHM0ErCMmy ( $file ) = @_;
my ( $handle );
_append( $file );
if( !$_lock{$file}{'tmp'} ) {
$_lock{$file}{'tmp'} = $file;
$_lock{$file}{'tmp'} =~ s/(.*)\.(.*)/$1\.tmp/;
}
if( !open( $handle, ">$_lock{$file}{'tmp'}" )) { return undef; }
return $handle;
}
sub _append {
my ( $file ) = @_;
if( $_lock{$file} ) { return; }
$_lock{$file}{'name'} = $file;
$_lock{$file}{'name'} =~ s/(.*)\.(.*)/$1\.lck/;
open( $_lock{$file}{'handle'}, ">$_lock{$file}{'name'}" );
my $count = 0;
while( !flock( $_lock{$file}{'handle'}, 2 )) {
sleep( 1 );
if( $count++ > 10 ) {
print '[error]Sarver Busy.';
exit;
} } }
1;
0835nobodyさん
2005/12/08(木) 21:14:40ID:pHM0ErCMrequire './filelock.pl';
$file = filelock::readOpen( "count.dat" );
$data = <$file>;
close( $file );
$data = $data + 1;
$file = filelock::writeOpen( "count.dat" );
print $file $data;
close( $file );
0836nobodyさん
2005/12/08(木) 23:57:56ID:???斜め読みしただけだから適当に。
ノンブロッキングロックじゃないと、whileループ内は無駄。
test.txtとtest.datが同じファイルと見なされる。
ロックを解除してるところがない?
サンプルスクリプトはロックが壊れる典型。
0837nobodyさん
2005/12/09(金) 00:42:03ID:???解答ありがとうございます。
>ノンブロッキングロックじゃないと、whileループ内は無駄。
そうですね。2(LOCK_EX)ではなくて2|4(LOCK_EX|LOCK_NB)
とすればokですね。
>test.txtとtest.datが同じファイルと見なされる。
まぁ、これは仕様という事で…(^^;
>ロックを解除してるところがない?
ENDの中のcloseで解除しているつもりなのですが
closeではロックは自動的解除されないのでしょうか?
>サンプルスクリプトはロックが壊れる典型。
どういう場合にロックが壊れるのでしょうか?
ご掲示頂けるとありがたいです。
0838nobodyさん
2005/12/09(金) 03:18:54ID:???ENDブロックは、スクリプトの処理の最後で処理されるので、
自動でアンロックさせたいのなら、返すファイルハンドルをオブジェクトにして、
DESTROYブロックを使ってアンロックさせる。
ついでにcloseも再定義。
ロックについては
http://web.archive.org/web/20040216083853/www98.sakura.ne.jp/~jun/perl/flock.html
0839833
2005/12/09(金) 03:47:51ID:???意図的にENDブロックに書いています。オブジェクトを作ってDEST
ROYブロックでアンロックする方法も考えたのですが…
hoge01.pl
read "data01.dat"
read "data02.dat"
-> hoge02.pl
write"data01.dat"
write"data02.dat"
-> hoge03.pl
write"data03.dat"
end
↑こんな感じで読み書きしたい場合、ファイルアクセスする可能
性のある所全てでオブジェクトを保持していないといけないので、
意図的にグローバルに情報を置いて、スクリプトの終わりでEND
ブロック内で一括に処理したのです。
ところで、"closeも再定義"って何ですか?
0840nobodyさん
2005/12/09(金) 12:08:16ID:???closeでロックの開放をするのなら、自前のcloseを書いて、
そこで必要な操作を行ってから、CORE::closeを呼び出すという感じで。
と、考えていたのだけど、
どうも考え方が違ってたっぽいか。
0841833
2005/12/09(金) 15:36:13ID:???readOpen
戻り値 : ファイルハンドル
機能 : 指定されたファイルの拡張子をlckに変えたファイルを
flockして指定されたファイルをオープン。flockが10秒以上で
きない場合は異常終了。
writeOpen
戻り値 : ファイルハンドル
機能 : 指定されたファイルの拡張子をlckに変えたファイルを
flockして指定されたファイルの拡張子をtmpに変えたファイル
をオープン。flockが10秒以上できない場合は異常終了。
END
機能 : readOpen,writeOpenでロックされたファイル(*.lck)を
close。writeOpenで返したのファイル(ハンドル)を元の名前に
リネーム。(*.tmp→*.元の拡張子)
引き続き、何か欠点や改良点があれば指摘して頂けるとありがたいです。
0842nobodyさん
2005/12/09(金) 16:10:37ID:???致命的にやばい点:
ENDの中でlockファイルをcloseした時点でflockは外れるので、
その後のunlockとtmpファイルのrenameがロックなしで行われる。
改善した方がいい点:
readしかしない場合でも排他的にロックしてしまうのは嬉しくない。
ENDが実行されるまでロック状態が持続するので、ロックの保持
期間が長くなりそうだしdaemon的プログラムだとどうすんの?
tmpの書き込み中に問題がでて取りやめたいときの手段がない
(やろうと思えば%filelock::_lockいじる手はあるが...)
リトライ回数が尽きたときにいきなりexitするのは汎用性がない。
せめてdieにしとけばevalでトラップする余地があるのだが。
0843833
2005/12/09(金) 17:26:00ID:???そうですね。renameは一番最初にやるとして、その後にunlink→
closeでしょうか?closeの前にunlinkってできるのでしょうか?
>readしかしない場合でも排他的にロックしてしまうのは嬉しくない。
ここでは省略しましたが、
unlockFile( $filename )
機能 : 強制的に指定されたファイルのロックを解除する。
というルーチンがあります。自分は、デフォルトは「最後まで排
他的にロック」。オプションで「指定したファイルのロックを解除」
っていう感じで考えてます。この方が間違いが無いと思うので。
>tmpの書き込み中に問題がでて取りやめたいときの手段
そうですね。これは、abortLockみたいなルーチンを作って最後の
ENDブロックの中でrenameしないようにすれば良いんじゃないで
しょうか?
>リトライ回数が尽きたときにいきなりexitするのは汎用性がない。
if( $count++ > 10 ) { die "flock busy" }
こんな感じで良いですかね?
まだまだ経験が浅いので、先輩諸氏からの助言は為になります。
他にも欠点や改良点があれば指摘して頂けるとありがたいです。
0844nobodyさん
2005/12/09(金) 21:41:26ID:???「ファイルを変更する(可能性がある)場合に排他ロック、読むだけで済む場合は共有ロック」
というのはひとつのセオリーだけれども、なぜそれがセオリーなのか、そもそもファイルロックとは何なのかを調べるなどして考えてみましょう。
>readしかしない場合でも排他的にロックしてしまうのは嬉しくない。
という >>842 の指摘にはまったく同意で、デメリットはいくらも思いつくけれど残念ながらメリットはひとつも思い浮かびません。
見境なしに排他ロックというのではファイルロックの魅力が半減以下です。
またファイルを利用している、いないに関わらずロックを離さないというのはお行儀が今ひとつ。各プロセスの実行時間が充分に短く、また起動頻度が比較的低ければ問題は出づらいでしょうけれど、少なくとも誰かに勧めることができるやり方じゃないですね。
0845833
2005/12/09(金) 22:03:55ID:???前作にあったバグ(read→write→readした時に*.tmpファイルから
読まない)も修正しています。
open
パラメータ:通常のopenと一緒だけど使えるのは'>'と'<'のみ。
戻り値:ファイルハンドル
機能:指定されたファイルの拡張子をlckに変えたファイルを
flockして指定されたファイルをオープン。flockが10秒以上で
きない場合は異常終了。
close
パラメータ:openで得られたファイルハンドルとオプション。
機能 : 指定されたファイルハンドルを閉じます。オプションで
1を指定するとロックを解除して書き込みがある場合はリネーム
して反映。2を指定するとロックを解除して書き込みがある場合
は*.tmpファイルを削除(つまり書き込みをキャンセル)
END
機能 : *.lckをclose&unlink。*.tmpがある場合は、元のファイ
ル名にリネーム。
package filelock;
our %_FileList;
our %_HandleList;
sub END {
foreach my $filename ( keys %_FileList ) {
if( $_FileList{$filename}{'temp'} ) { rename( $_FileList{$filename}{'temp'}, $filename ) }
unlink( $_FileList{$filename}{'lock'} );
close( $_FileList{$filename}{'handle'} );
} }
0846833
2005/12/09(金) 22:05:50ID:???my ( $filename ) = @_;
my ( $handle, $tempfile, $mode );
if( $filename =~ /^>.*/ ) { $filename =~ s/^>(.*)/$1/; $mode = 2 }
elsif( $filename =~ /^<.*/ ) { $filename =~ s/^<(.*)/$1/; $mode = 1 }
else { return undef; }
if( $mode == 1 && !( -e $filename )) { return undef }
if( !$_FileList{$filename} ) {
my $lockname = $filename;
$lockname =~ s/(.*)\.(.*)/$1\.lck/;
open( $handle, ">$lockname" );
my $count = 0;
while( !flock( $handle, ( 2 | 4 ))) {
sleep( 1 );
if( $count++ > 10 ) { die "flock busy" }
}
$_FileList{$filename}{'lock'} = $lockname;
$_FileList{$filename}{'handle'} = $handle;
}
$tempfile = $filename;
if( $mode == 1 ) {
if( $_FileList{$filename}{'temp'} ) { $tempfile = $_FileList{$filename}{'temp'} }
if( !open( $handle, "<$tempfile" )) { die "file open error(read)" }
} elsif( $mode == 2 ) {
if( $_FileList{$filename}{'temp'} ) { $tempfile = $_FileList{$filename}{'temp'} }
else {
$tempfile =~ s/(.*)\.(.*)/$1\.tmp/;
$_FileList{$filename}{'temp'} = $tempfile;
}
if( !open( $handle, ">$tempfile" )) { die "file open error(write)" }
0847833
2005/12/09(金) 22:07:31ID:???$_HandleList{$handle} = $filename;
return $handle;
}
sub close {
my ( $handle, $option ) = @_;
if( $option && ( $option == 1 || $option == 2 )) {
close( $handle );
my $filename = $_HandleList{$handle};
if( $_FileList{$filename}{'temp'} && $option == 1 ) { rename( $_FileList{$filename}{'temp'}, $filename ) }
elsif( $_FileList{$filename}{'temp'} && $option == 2 ) { unlink( $_FileList{$filename}{'temp'} ) }
unlink( $_FileList{$filename}{'lock'} );
close( $_FileList{$filename}{'handle'} );
delete( $_FileList{$filename} );
delete( $_HandleList{$handle} );
} else {
close( $handle );
delete( $_HandleList{$handle} );
} }
1;
例:
require './filelock.pl';
$file = filelock::open( "<count.dat" );
$data = <$file>;
filelock::close( $file );
$data = $data + 1;
$file = filelock::open( ">count.dat" );
print $file $data;
filelock::close( $file, 1 );
0848nobodyさん
2005/12/11(日) 11:36:06ID:???0849nobodyさん
2005/12/11(日) 15:20:09ID:???0850nobodyさん
2005/12/11(日) 23:38:47ID:???と言ったところで、その案に穴があるか、書けないか
どっちかだろ?…という訳で、とりあえず
>>848
じ ゃ あ 、 そ の や り 方 を 書 い て み ろ
0851nobodyさん
2005/12/12(月) 10:42:51ID:???(Aが正常にロックを取得した状態から)
B: open
A: unlink
C: open
A: close
B: flock(成功する)
C: flock(成功する)
flockを使うときはロックファイルは一度作ったら消さないのが
わかりやすい。
どうしても削除したければ、その操作をするためのロックを
別にするとかややこしいことをする羽目になる。
0852nobodyさん
2005/12/12(月) 21:10:57ID:???ん?Aがロックした状態なんだよね?
B: open -> Aがロック中なので開けない
A: unlink -> 自分がロック中なので削除できる
C: open -> Aがロック中なので開けない
A: close -> 自分のロックを外す
B: flock(成功する) -> Bがロック
C: flock(成功する) -> Bがロック中なので開けない…のでわ?
0853nobodyさん
2005/12/12(月) 21:21:39ID:???flockによるロック中でもopenはできるのでBはopenできるし、
Aが削除した後はそのファイルは存在しないんだから、
Cは新たに同じ名前の別のファイルを作ってopenできる。
そしてことのきBとCがそれぞれロックファイルだと思って
開いたファイルは実は別のものになるというのが問題
なのです。
0854nobodyさん
2005/12/12(月) 22:29:46ID:???削除したらロックが外れるのは初耳だ。
つちの環境だと
open -> unlink -> sleep(10) -> close
で、sleep(10)の間はflockできないんだが…。
>flockによるロック中でもopenはできるので
>>833(845)のソースではopenする前にflockの
確認してると思うけど、そりゃ、perlが内部で
flock処理に入ったタイミングで他プロセスが
openしたらできるかもしれないが、そしたら
flock自体意味無しって事になるぞ?
0855nobodyさん
2005/12/12(月) 22:33:12ID:???誤:つちの環境
とりあえず>>853は>>833(845)のソースを実際に実行して
穴があってから発言したら?
"俺予想"だけで発言しても意味無いよ。
0856nobodyさん
2005/12/12(月) 22:39:11ID:???削除したらロックがはずれるのではなくて、同じ名前のロック
ファイルを別に作れてしまう。sleep(10)の間にロックファイルを
openしようとしたら存在しないので新しいファイルが作られてしまう
から、当然flockもできるでしょ。
> openする前にflockの 確認してると思うけど
flockはopenした後のファイルハンドルに対する操作
だから、openしてないのにできるわけないよ。ロックファイルの
openと操作したいファイルのopenを混同してない?
0857nobodyさん
2005/12/13(火) 00:46:00ID:???や
sub open
や
sub close
見ただけで、他のところ見る気なくすね。
0858nobodyさん
2005/12/13(火) 01:24:36ID:???なるほどね。
しかし、open→flockの間にflockされる問題を回避する事なんてできるの?
>>857
スレタイを百万回読んでスレの趣旨が名前なんて関係無いという事に気付け。
0859nobodyさん
2005/12/13(火) 23:21:49ID:???げらげら
sub openとか、package filelockなんか平気で使ってる奴はやっぱりレベル低いねえ。
0860nobodyさん
2005/12/14(水) 00:31:33ID:???0861nobodyさん
2005/12/14(水) 05:19:12ID:???漏れは>>858だけど>>833じゃないんだけどなぁ。
なんか、このスレは文句ばっかりで意欲的に書き込んでる>>833を
援護しただけなんだけど、文句言うだけがスレの趣旨みたいね。
スレ汚しスマソ。
0862nobodyさん
2005/12/14(水) 07:59:40ID:???じゃなくて、その問題が起きないようにしないとロックになってないわけよ。
一番簡単なのは851で指摘してる通りロックファイルを削除しないこと。
ただの文句としか言えない書き込みがあるのも確かだが、まじめに
バグを指摘してるのにひとくくりにして文句とか言われてもなぁ。
0863833
2005/12/14(水) 10:14:13ID:???色々とご指摘ありがとうございます。ロックファイルをunlinkす
ると、close前にロックファイルがopen(作成)できてしまう問題を
回避する為にunlinkしない事にしました。
しかし、それだと*.lckが沢山できてしまうので、filelockディレ
クトリを作ってその中に作る事にしました。同様に書き込み用の
テンポラリファイルもその中に作るようにしたので、今までの
*.lckや*.tmpファイル名が使えなかったり拡張子だけが違うファ
イルが扱えない問題も無くなりました。
その代わり、各ディレクトリにfilelockという名前のディレクト
リができます。以下にソースを晒します。
sub open {
my ( $filename ) = @_;
my ( $handle, $mode );
if( $filename =~ /^>.*/ ) { $filename =~ s/^>(.*)/$1/; $mode = 2 }
elsif( $filename =~ /^<.*/ ) { $filename =~ s/^<(.*)/$1/; $mode = 1 }
else { return undef; }
if( $mode == 1 && !( -e $filename )) { return undef; }
$filename =~ /(.*)(\\|\/)(.*)/;
if(! -d "$1$2filelock") {
mkdir("$1$2filelock", 0755);
mkdir("$1$2filelock/tmp", 0755);
}
if( !$_FileList{$filename} ) {
$filename =~ /(.*)(\\|\/)(.*)/;
my $lockfile = $3 eq '' ? "$1$2filelock/$filename" : "$1$2filelock/$3";
if( !open( $handle, ">$lockfile" )) { die "file open error" }
my $count = 0;
while( !flock( $handle, ( 2 | 4 ))) {
0864833
2005/12/14(水) 10:14:38ID:???if( $count++ > 10 ) { die "flock busy($lockfile)" }
}
$_FileList{$filename}{'lock'} = $lockfile;
$_FileList{$filename}{'handle'} = $handle;
}
if( $mode == 1 ) {
my $openfile = $filename;
if( $_FileList{$filename}{'temp'} ) { $openfile = $_FileList{$filename}{'temp'}; }
if( !open( $handle, "<$openfile" )) { die "file open error" }
$_HandleList{$handle} = $filename;
return $handle;
} elsif( $mode == 2 ) {
my $openfile = $filename;
if( $_FileList{$filename}{'temp'} ) { $openfile = $_FileList{$filename}{'temp'};
} else {
$filename =~ /(.*)(\\|\/)(.*)/;
my $tempfile = $3 eq '' ? "$1$2filelock/tmp/$filename" : "$1$2filelock/tmp/$3";
$_FileList{$filename}{'temp'} = $tempfile;
}
if( !open( $handle, ">$openfile" )) { die "file open error" }
$_HandleList{$handle} = $filename;
return $handle;
}
return undef;
}
引き続き、欠点や改良点があれば指摘して頂けるとありがたいです。
0865nobodyさん
2005/12/14(水) 14:36:11ID:???いくらコード書いたって無駄だろ。
少なくとも誰も使わんと思うが。
0866nobodyさん
2005/12/14(水) 20:09:27ID:???0867nobodyさん
2005/12/15(木) 00:56:13ID:???0868nobodyさん
2005/12/15(木) 06:51:32ID:???すげー苦しい言い訳だ。>>865が文句に見えないなら
小学校の国語からやりなおした方が良いよマジで。
とりあえず漏れが>>865が文句だと思う具体的な根拠は…
・どこが問題なのか具体的な事が書かれていない
・自分の中の意見を「誰も」と書くことで皆と同じだと思い込んでる
・文章が全体的に罵倒した口調。何かイヤな事でもあったの?(w
>>833
最初に比べると随分マシになったと思うよ。
具体案を何も提示しないアホな煽りに構わず頑張って欲しい。
0870nobodyさん
2005/12/15(木) 09:24:29ID:???混在してるの?
0871nobodyさん
2005/12/15(木) 09:53:36ID:???まだ君には早いよ。
0872nobodyさん
2005/12/15(木) 10:22:47ID:???やってんでしょうから、大目に見てやんなって。
0873nobodyさん
2005/12/15(木) 11:10:51ID:???0874nobodyさん
2005/12/15(木) 12:01:28ID:???ファイルが無かったりオプションの指定が違ったりだとundefしてて、
ファイルに書き込めなかったりロックできなかったりするとdieしてる。
たぶん、見た感じだとundefは想定内(?)のエラー。dieは想定外(?)
のエラーって感じじゃないのかな?
0875nobodyさん
2005/12/15(木) 12:09:03ID:???とりあえず>>865>>873が言う「排他制御」と>>833のソースの
排他制御は何が違うのか具体的に書いてくれまいか?
0878nobodyさん
2005/12/16(金) 01:57:10ID:???排他的なロックに対しては、それで良いと思う。テンポラリファイルを作って書き込み
エラーにも対応してるし。しかし、それで全てOKという訳では無い。
例えばAというファイルをプロセス1〜10が同時に読み込み処理が行われて書き込み処理が
無い場合を考えてみよう。プロセス1が読み込み終わるまでプロセス2は読み込み処理を
行えない。読み込み処理だけならば排他的なロックは必要無いのに。
まぁ、それをわかっていて>>833が何でも排他的なロックを使っているなら良いのだが…
0879nobodyさん
2005/12/16(金) 03:04:17ID:???× 読み込み処理だけならば排他的なロックは必要無いのに。
○ 読み込み処理だけならば排他的なロックは必要無いケースもあるのに。
0880nobodyさん
2005/12/16(金) 05:43:26ID:nqW99XKPすごく邪魔
0881nobodyさん
2005/12/16(金) 05:44:47ID:nqW99XKPって思ったり。
0882nobodyさん
2005/12/16(金) 12:06:00ID:???0883nobodyさん
2005/12/17(土) 01:28:51ID:???開かないと思うけど…。それに追記に対応してないみたいだから
1回目も2回目も「新規ファイル作成」扱いになるんだよね?
0884nobodyさん
2005/12/17(土) 02:42:54ID:???> my $openfile = $filename;
> if( $_FileList{$filename}{'temp'} ) { $openfile = $_FileList{$filename}{'temp'};
てなことになってる。
「書き込みを行って読み込み」を行うとすると、
まず書き込みで$filenameに書き込まれて、
読み込みで$_FileList{$filename}{'temp'}が読まれることになると思われる。
0885nobodyさん
2006/01/08(日) 16:25:04ID:???0886nobodyさん
2006/01/11(水) 15:20:26ID:???0887nobodyさん
2006/01/11(水) 18:09:12ID:???r' ,v^v^v^v^v^il / ヽ
l / jニニコ iニニ!. / ジ き ぼ l
i~^' fエ:エi fエエ)Fi ! ャ れ く l
ヽr > V ! イ い は l
l !ー―‐r l <. ア な l
__,.r-‐人 `ー―' ノ_ ヽ ン /
ノ ! ! ゙ー‐-- ̄--‐'"ハ ~^i \_ _ノ
ヽ ! ヽ、_ _.ノ i \  ̄ ̄ ̄ ̄
ヾV / ! /.入
0888nobodyさん
2006/01/23(月) 18:41:58ID:???$nowsec=time;
$lockname="./lock/lock_".$nowsec;
$basename="./lock/lock";
while (1){
if (rename $basename,$lockname){&process()};
$n++;
if ($n>=5){&error()};
sleep 1;
};
opendir (LOCKDIR,lock);
@filelist=readdir(LOCKDIR);
closedir(LOCKDIR);
foreach $filename (@filelist) {
if ($filename=~/_/) {
($dest,$locktime)=split(/_/,$filename,2);
unless ($locktime==$nowsec){
$timedif=$nowsec-$locktime;
if ($timedif>=5){
rename $filename,$lockname;
};
};
};
sub process{
&backname()
}
sub backname{
rename $lockname,$filename;
}
0889nobodyさん
2006/01/28(土) 10:06:37ID:JFqaWvHV先にファイルを開いておいて、それからロックするものですか?
オープン前に排他制御かけるのは無駄ですか?
0890nobodyさん
2006/01/28(土) 12:03:17ID:???0892889
2006/01/29(日) 07:30:55ID:rUKuWvJeこんな感じでいいのでしょうか?
上書きする部分だけループにしています。添削してもらえませんか?
open(F1,">$file1")||die();
flock(F1,LOCK_EX);
open(F2,">$file2")||die();
flock(F2,LOCK_EX);
foreach(@data){
($aaa,$bbb)=split(',',$_,2);
print F1 "$aaa,$bbb\n";
print F2 "$aaa,$bbb\n";
}
close(F1);
close(F2);
0893nobodyさん
2006/01/29(日) 08:51:40ID:1QlgYllq0894nobodyさん
2006/01/29(日) 09:17:31ID:???書き出したファイルを読み出すことは無いの?
@dataで書き込むデータは常に増えて、減ることはないの?
上二つのどちらかでも該当すると ">"でオープンするのはまずいと思われ。
0895nobodyさん
2006/01/29(日) 10:16:26ID:???http://search.cpan.org/~nwclark/perl-5.8.7/pod/perlfunc.pod#flock
http://www.kt.rim.or.jp/~kbk/perl-5.8/perlfaq5.html#how_can_i_lock_a_file
http://web.archive.org/web/20040216083853/www98.sakura.ne.jp/~jun/perl/flock.html
http://homepage1.nifty.com/glass/tom_neko/web/web_04.html
http://www.bioinfo.jp/tips.html#flock
http://www.din.or.jp/~ohzaki/perl.htm#File_Lock
0896flock
2006/01/29(日) 16:44:40ID:rUKuWvJeF1とF2で別々のファイルを開くのに、ロックは1つで良いのですか!?
>>894
このcgiファイルでは、このF1やF2は上書きだけで終了です。
このスクリプトの中でF1およびF2の中に追加項目があったりするので、それを足したのをまた同じF1やF2に上書きするという処理をさせています。
ですので、このファイルでは
>書き出したファイルを読み出すことは無いの?
>@dataで書き込むデータは常に増えて、減ることはないの?
ということは無いです。
ただですね、他のcgiファイルでは読込みがあります。
F1とF2では用途が違うので同じ内容を2つに分けていますが、片方はダウンロードして使いたいのでCSVファイル、もう片方が他で読み込んで使う用途にtxtファイルにしています。
このtxtファイルの方も、他のcgiファイルのスクリプトの中で読み込みはしますが、項目が減ったり増えたりすることはありません。
私は、この部分が変に冗長になっているのではないかと思い、他に良い書き方は無いかと考えてみたのですが
どうしても他の方法が浮かばなかったのでこちらの専門スレに投稿させて頂いた次第です。
良かったら、他の書き方があればご教授願えませんでしょうか?
>>895
ありがとうございます。
その内4つは調べている段階で既読でした。
他のサイトを拝見してきます。
0897flock
2006/01/29(日) 17:31:41ID:rUKuWvJe今拝見してきたのですが、端的にflockの使い方良し悪しについて述べられているサイトを見つけるのが難しい中、プロセスから易しく書かれたものが見つけられました。
ありがとうございました。
その中にあった
http://web.archive.org/web/20040216083853/www98.sakura.ne.jp/~jun/perl/flock.html#99
の「ゴミ」というところに似た書き方をしているのではと、かなり不安になりました。
特にCSVファイルの方は、サーバからダウンロードして後から情報の閲覧や整理に使いたいので
(@dataに追加するデータは、ある条件を満たすもののみ○、そうでないものは何も書かないというごく簡単なものですが)
○では無いのに○が付いてしまったり、またはその逆などのエラーがあると困ってしまうのです。
ますますもって、このままで良いのか不安になってきました。
ファイルロックについて、このサイトのようにプロセスから細かく記されている書籍などはご存じないでしょうか?
もし、お暇でしたら私のスクリプトの不安箇所の訂正などして頂けたらありがたいのですが....
0898nobodyさん
2006/01/29(日) 18:07:38ID:???open(F1,"+<$file1")||die();
flock(F1,LOCK_EX);
open(F2,"+<$file2")||die();
flock(F2,LOCK_EX);
...
truncate(F2, tell(F2));
close(F2);
truncate(F1, tell(F1));
close(F1);
($file1,2は既に存在するとして)こんな感じかな。
同じ内容なら、一つのファイルにすることを考えた方がいいかも。
リンク張るとか。
> 「ゴミ」というところに似た書き方をしているのではと、かなり不安になりました。
同じファイルに対して排他的なロックすることで起こるデッドロックだね。
関係があるとしたら、File2とFile1を逆順に排他的にロックするプログラムが有るとき。
そのときはデッドロックを引き起こす可能性がある。
0899nobodyさん
2006/01/29(日) 19:15:17ID:???lock は結局読み込みから書き込みまでの間に何をするかなんだよな。
(読み込みが含まれるのは読み込んで書き込むまでの間に他の
プロセスが書き込みを行ってしまっていた場合に、新たに書き込む
データが既存のデータを壊してしまうから。)
だから本当は書き込みのところだけ晒されても正しいのかどうかは
判断できない。
ロックで具体的にこうしろというコードが表に出てこないのは
そういう理由もある。
0900はは
2006/03/02(木) 23:54:04ID:KQkmhtbv0901nobodyさん
2006/03/03(金) 01:03:50ID:QWJoZw1qif (!open(ORI,"$original_file")) { &error; }
if (!open(TMP,"> $tmp_file")) { &error;}
if (!open(LOCK, "$lock_file")){&error;}
flock(LOCK, 2);
while ($_ = <ORI>) {
#各種更新処理
print TMP "$changed_line";
};
close(ORI);
close(TMP);
&lock;
flock(LOCK, 8);
close(LOCK);
sub lock {
$list = `ls $ls`;
@lists = split(/\s+/,$list);
@lists = grep(/\.tmp/,@lists);
@lists = grep(!/$tmp_file/,@lists);
if (@lists) {
if (-e "$tmp_file") { unlink("$tmp_file"); }
&error;
}
if (!rename("$tmp_file","$original_file")) { &error; } ;
chmod 0666,"$original_file";
}
システムが瀕死の状態ん時に(年に1度ぐらい)壊れるが。
0902nobodyさん
2006/03/03(金) 02:34:58ID:???flock $lock, LOCK_EX|LOCK_NB or die;
open my $in, "< $data_file" or die;
open my $out, "> $tmp_file" or die;
while (my $line = <$in>) {
# bra bra bra
. . . . .
print $out $line or die;
}
close $out or die;
close $in;
rename $tmp_file, $data_file or die;
close $lock;
とかでいいんじゃね?
0903nobodyさん
2006/03/03(金) 20:34:19ID:QWJoZw1qflockを信じればそれでもいけるが、テンポファイルが何らかの障害で生き残った場合
リネームで致命傷。
ユニークなファイル名にしといた方が安全かなと。
0904nobodyさん
2006/03/03(金) 22:52:47ID:???0905nobodyさん
2006/03/04(土) 01:20:31ID:???つか、flockすんならテンポラリファイルいらねーだろ。
0906nobodyさん
2006/03/04(土) 03:20:16ID:???sysopen my $fh, $file, O_RDWR|O_CREAT|O_EXLOCK, 0600 or die $!;
my $sz_file = -s $fh;
sysread $fh, my($buf), $sz_file or die $!;
my @data = split /\n/, $buf;
:
:
my $sz_data = length($buf = join "\n", @data);
sysseek $fh, 0, SEEK_SET or die $!;
if ($sz_data < $sz_file) {
$buf .= "\n" x ($sz_file - $sz_data);
syswrite $fh, $buf, $sz_file or die $!;
truncate $fh, $sz_data or die $!;
} else {
syswrite $fh, $buf, $sz_data or die $!;
}
close $fh;
0908nobodyさん
2006/03/04(土) 20:19:13ID:???まとめたサイトってありますか?
0910nobodyさん
2006/03/05(日) 00:08:23ID:j4KtSVTyそこまで考えるとDB使っても無理。
データは壊れるものと思って、定期的なバックアップは必要。
もちDBのほうが壊れにくいが、それでもMySQLなんて更新多いと壊れる事はある。
このスレはDB使えなくて、それでも極力ファイル破損させたくないって人が対象だろうから、
flock+店舗ファイルが正解なんじゃない?
共用鯖使ってる人が多いだろうけど、そういう鯖は完全に落ちなくてもflock効いてない時結構あったよ。
俺の借りてた鯖の場合は店舗ファイル使って、ずいぶん壊れにくくなったなぁと思うんだけど。
今は自鯖あるから俺もDB使っているけど。
0911nobodyさん
2006/03/05(日) 01:35:17ID:???flock $lock, LOCK_EX;
tie @data, "DB_File", $data_file, O_RDWR|O_CREAT, 0666, $DB_RECNO or die $!;
# 更新処理
untie @data;
close $lock;
これで壊れたことないんだけど、何か問題ある?
0913nobodyさん
2006/03/05(日) 10:29:48ID:???> LOCK_NB or die;
って、少しは待ってみるとかalarm仕込むとかしようよ。
0914nobodyさん
2006/03/06(月) 09:58:45ID:???> そこまで考えるとDB使っても無理。
SQLite3 なんかはトランザクション中に再起動や電源断があっても大丈夫って言ってるみたい。
やりかた次第じゃないかな。
0915nobodyさん
2006/03/06(月) 20:50:40ID:???0916nobodyさん
2006/03/06(月) 21:18:04ID:???0917nobodyさん
2006/07/14(金) 18:34:43ID:???このスレを参考にflockでかなりファイルが壊れなくなりました
頭が下がる思いです
で、最近処理速度が気になります。
無論ハード面での影響があるとは思いますがflockで処理するより
MySQLなどを使った方が処理速度は飛躍的に向上しますか?
えろいひと教えて下さい
0918nobodyさん
2006/08/18(金) 23:57:42ID:???データ構造が巨大かつ複雑で、そこから任意の情報をいやらしい感じに読み書きするような話なのであれば、RDBMS に SQL 渡して丸投げしたほうが *効率は* いいと思う。
餅は餅屋というやつだ。
0919七誌
2006/10/27(金) 22:34:40ID:Cj9z7A7l0920nobodyさん
2006/10/27(金) 22:50:51ID:???0921nobodyさん
2006/10/28(土) 16:57:21ID:???0922nobodyさん
2006/11/04(土) 13:00:42ID:???0923nobodyさん
2006/11/11(土) 18:19:40ID:umuRe6Kn0924nobodyさん
2006/11/28(火) 09:01:07ID:+OyZsB34ローカルの環境でカウンターのファイルロックの強度を試すのに、for文で1000回カウンターのファイルにアクセスするスクリプトを作り、
それをタブブラウザで10個開いておいて、全てのタブを再読み込みさせて10000回カウントされているのを見るのは有効な手段でしょうか?
またネットワークにつながっているもう一台のパソコンからも、さらに同時に更新をかけて、20000回カウントされてるかどうか見るのは有効でしょうか?
0925nobodyさん
2006/11/28(火) 09:11:11ID:???httpの同時セッション数が既定の2とかだとまったく意味ナサス。
素直にab(apache bench)とか使っとけ。
0926nobodyさん
2006/11/28(火) 10:46:03ID:???0927nobodyさん
2006/11/28(火) 11:35:28ID:???0928nobodyさん
2006/11/28(火) 13:00:47ID:???0929nobodyさん
2006/11/28(火) 16:34:07ID:???0930nobodyさん
2006/11/28(火) 17:08:23ID:???0931nobodyさん
2006/11/28(火) 19:23:59ID:???0932nobodyさん
2006/11/29(水) 00:11:52ID:???ロックには二種類しかない、駄目なロックと正しいロックだ。中間はない。
「ロックの強度」などと言うやつが作ったものは駄目なロックである可能性が非常に高い。
0933nobodyさん
2006/11/29(水) 03:37:00ID:???0934nobodyさん
2007/01/29(月) 15:46:57ID:MdfhpFZP0935nobodyさん
2007/01/29(月) 17:47:33ID:???うぃ〜うぃるうぃ〜うぃるろっきゅ〜
0936nobodyさん
2007/01/29(月) 18:21:17ID:???0937nobodyさん
2007/01/29(月) 18:45:24ID:???そうしてるけどデータファイル自体をロックする場合って
一時ファイルに書き出してデータファイル名にリネームした瞬間ロック解除扱いになるんだよね?
そうなるとロック待ちプロセスがデータファイルオープンしてファイルロック中にリネーム
されたらファイルが存在しなくなってファイルハンドルが無効になってファイルロックが偽を返すのかな?
0938nobodyさん
2007/01/29(月) 19:04:35ID:???0939nobodyさん
2007/01/30(火) 10:08:22ID:???> 一時ファイルに書き出してデータファイル名にリネーム
それ自体は何ら排他処理になっていない。書込途中のプロセス死亡と
いったケースでデータファイルが壊れるのを防ぐ為の手順。
ロックファイルを使わずに排他処理したいなら、
open my $fh, '+<', '/path/to/file' or die $!;
flock $fh, LOCK_EX;
...
close $fh;
のようになる。
0940nobodyさん
2007/04/16(月) 16:21:56ID:wXXA2dJL1つ疑問いいですか?
flockの有効範囲(?)っていうのがいまいち分からなくて。。
同一サーバ内、バーチャルドメインごと、1スクリプトごと。。。??
flockを使って、このスレにある方法を使い正しいロック方法の時だとします
ここまで読んだものから推測するとサーバ内であれば別のスクリプトから呼び出しても効きますよね?(ファイルハンドルが同じなら)
逆に言えばflockを使っているファイルハンドルを別のスクリプトで使ったら解除してしまうってことですか?
レン鯖みたいな共用鯖でよく使いそうなファイルハンドル(INとかOUTとか)でflockを使うと危険なんですかね?
0941nobodyさん
2007/04/16(月) 16:38:48ID:???0942nobodyさん
2007/04/16(月) 18:29:01ID:???Perlのflockは様々な実装があるので、ここではUnix互換OSのflock(2)が
使われた場合とすると、
・flockはOSの機能なので、機能するのはOSの範囲内。
・正しい書き方をすれば、別のプロセスがロックを外すことは無い。
・別プロセスからのflockの開放は可能らしい。
0943nobodyさん
2007/04/16(月) 18:31:45ID:???0944nobodyさん
2007/04/16(月) 19:58:57ID:???0945nobodyさん
2007/04/23(月) 18:26:23ID:???遅ればせながらォです
0946nobodyさん
2007/04/23(月) 20:20:20ID:???0947nobodyさん
2007/04/26(木) 17:01:49ID:???(OSが管理してるので)同じサーバ内でならflockでいい。
別のサーバからのアクセスもロックしたいなら
lockd動かしてfcntlでロックする。
0948nobodyさん
2007/04/29(日) 20:50:11ID:QRYQeqJ7mutex使えよ、アホ
0951nobodyさん
2007/04/30(月) 14:26:51ID:???独自に考えるべき
0952nobodyさん
2007/04/30(月) 17:20:06ID:???関する議論をするスレッドなんだよ。
しかもwebprog板なので、サーバーサイド限定だ。
すなわちWin限定の解は採点が低い。
0953nobodyさん
2007/04/30(月) 18:09:45ID:???0954nobodyさん
2007/04/30(月) 18:34:21ID:???0955nobodyさん
2007/04/30(月) 22:19:01ID:???0956nobodyさん
2007/05/01(火) 08:41:54ID:???0958nobodyさん
2007/05/03(木) 07:37:55ID:???0959nobodyさん
2007/11/12(月) 23:00:45ID:???0960nobodyさん
2007/11/25(日) 15:43:12ID:YhRNGWJK0961nobodyさん
2008/03/14(金) 20:29:09ID:???0962nobodyさん
2008/08/08(金) 02:57:43ID:???部分ロックしたいときに困る
0963nobodyさん
2008/08/08(金) 02:59:41ID:V81X7ey0そういうのって何で作られないの?何かわけがあるの?
0964nobodyさん
2008/08/08(金) 10:06:25ID:???管理はファイルごとに行うんじゃなくてファイルハンドルごとに行うんじゃないかい?
ま、ルールに則って処理しなければlockはいくらでも無視できるけど
0965nobodyさん
2008/08/08(金) 19:52:28ID:???mkdirとかを用いた方法だって、あくまで"処理のロック"だろ。
その処理ってのがファイルアクセスだったときにファイルロックになるだけでさ。
わざわざロック専用のファイル作ってそれにflockかける場合のこと考えると、「対象としてのファイルがなければロックできない」ってのはどうにも無駄な制限だと思うんだけど。
って書いたけどIDだけでの管理は共用鯖とかだと現実的じゃないな。
0966nobodyさん
2008/08/08(金) 20:28:34ID:???perlなら組み込み関数あるし、CPANにもライブラリあるよ。
0967nobodyさん
2009/09/07(月) 18:18:57ID:0FwHnD5napacheのアクセスログの様にとにかく最後尾に追記するだけの場合、排他処理は必要ですか?
use Fcntl;
sysopen(OUT, $FileName, O_WRONLY|O_CREAT|O_APPEND);
print OUT "aaa\n";
close(OUT);
これだけで済めばいいな〜というのは甘い考えでしょうか?
0968nobodyさん
2009/09/09(水) 17:11:40ID:???0969nobodyさん
2009/09/09(水) 17:27:59ID:jdeXznBzレスありがとうございます。
後で編集するので書き込まれる順序は特に気にしませんが
一応flock程度はやっておこうかなと思ってます。
0970nobodyさん
2009/09/13(日) 16:22:21ID:YylJyw/3一回のシステムコールで書き込まれるようにすれば?
syswrite を使うか、バッファを無効にする。
0971nobodyさん
2009/10/08(木) 14:28:23ID:???ロックは必須でしょう?
0972nobodyさん
2009/10/12(月) 23:17:19ID:???http://www.bioinfo.jp/tips.html#append に詳しく書いてある。
確認してみれ。
0973nobodyさん
2009/10/19(月) 19:57:43ID:???0974nobodyさん
2010/12/07(火) 00:32:09ID:???0975nobodyさん
2010/12/07(火) 00:36:21ID:???0976nobodyさん
2010/12/07(火) 00:42:44ID:???0977nobodyさん
2010/12/07(火) 00:48:12ID:???0978nobodyさん
2010/12/07(火) 00:52:46ID:???0979nobodyさん
2010/12/07(火) 01:02:14ID:???0980nobodyさん
2010/12/07(火) 01:08:46ID:???0981nobodyさん
2010/12/07(火) 01:14:46ID:???レス数が950を超えています。1000を超えると書き込みができなくなります。