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

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

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん02/06/23 10:18ID:eY2l+Gw1
どんな環境でも使えて、軽くて、頑丈なロックを考えようじゃありません
024722802/08/06 00:52ID:eY1Nkha6
my @lines=<DB> || &error('読み込みエラー');
にしたら
最初の一行しか読まないんですが・・
すいません・・・
0248nobodyさん02/08/06 01:13ID:???
評価順位って知ってる?
(@lines=<DB>)
その他力本願ぶりじゃ先は真っ暗っぽいね
024922802/08/06 01:14ID:HdiBMgeW
or にしたら
ちゃんと動きました
or と || とは違うんですか?
はぁ・・
025022802/08/06 01:29ID:AoKqt/pr
おお、わかりました
ありがとうございます
0251nobodyさん02/08/06 06:51ID:???
>>248
ハァーーーーーーーー


眠たい
0252 02/08/06 09:00ID:???
>>251
何が眠たいんだ? 
my (@lines=<DB>) || &error('読み込みエラー');
で動いてるんだが、向学の為に教えて欲しい
0253 ◆JAPH9PWA 02/08/06 09:12ID:???
>>249
orは||より優先度がずっと低いんだよ。
だから
@lines = <DB> or error;
は
(@lines = <DB>) or error;
と評価され、
@lines = <DB> || error;
は
@lines = (<DB> || error);
と評価される。
||演算子のオペランドはスカラコンテキストで評価されるから、
結果として一行しか読み込まれないことになる、というわけね。

>>252
< my(@lines = <DB>)
> (my(@lines) = <DB>)
0254 02/08/06 15:22ID:???
>>253
優先度を云々するのなら、= と || および = と or について言わないと意味ナイだろ。
0255 ◆JAPH9PWA 02/08/07 10:19ID:???
>>254
そういえばそうだ。肝心な所が抜けててごめん。

>>253 追記
とりあえず、代入演算子は比較的優先順位が低くなってるんだよ。
例えば、算術演算子や比較演算子などは全て代入演算子より優先度が高い。
だからこそ
$foo = 100 + 200; という式が
($foo = 100) + 200; ではなく、$foo = (100 + 200);と評価される。
で、||や&&といった演算子は代入演算子よりも優先順位が高いため、
加算演算子と同様の評価順序になるってわけ。
しかしながら、orやandといった演算子の優先順位は代入演算子のそれより低いので、
このケースの場合は期待通りに動くわけだね。

詳細についてはついてはperldoc perlopを参照のこと。
0256 ◆JAPH9PWA 02/08/07 10:21ID:???
ていうかここはファイルロックスレじゃないか!
スレ違いもいいとこだね。とほほ…
025722802/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ロックを少し改造したものをあわせて使ってます
そのまま使うとエラーでロックを外した瞬間に書き込みが重なってしまうようなので・・・
ありがとうございました
025823002/08/10 06:54ID:???
>>257
>そのまま使うとエラーでロックを外した瞬間に書き込みが重なってしまう

ロックを外したら、もはやそのプロセスは書き込まないはず。
まさか&errorでexitせずに、実行続けてるとか?

mkdir式が有効なのは、flockがダメだったからかもしれないが、
処理が遅くなるのとタイムアウトがある事で、読み書きが集中
しないようになった効果かもしれない。

質問者は問題が解決しさえすればいいんだが、
flockとmkdir式の併用なんて気持ちわるい結末だなぁ。
025922802/08/10 18:58ID:???
>ロックを外したら、もはやそのプロセスは書き込まないはず。
どんなエラーでもロックを外してしまうので
書き込み中の人がいて、それ以外の人がエラー出してロックを外してしまう
というのが問題でした
上で書いてるのはちょっと違いました。。

いろいろ教えて頂いたのに、はっきり原因を解明せずに
気持ち悪い結末にしてしまって申し訳ないですが
上のflockのみではprintで失敗したらどうしようもないのなら
mkdirを併用する方法はいいんじゃないかと思うんですが・・
026023002/08/10 22:16ID:???
>>259
書き込み中の人がいるとしたら、その人しかロックが成功していないので、
それ以外の人がロックを外す事はありえないのが排他制御。
mkdir式の場合、ロック成功したプロセスがエラーで外すなら問題ないわけ。
通常、ロックを成功してないプロセスがロックを外すようなのはバグ。
flockの場合はロックかけたプロセス以外は外せないよ。

> printで失敗したらどうしようもない
mkdirを併用しても同じ状況だけど。
print LOG @lines or &error('書き込みエラー');
でOK。truncateする前にやめればデータは壊れない。

とにかく、mkdir式にするならflockは必要ないので消そうよ。
0261nobodyさん02/08/11 12:39ID:???
結局KENTかよ!!!
0262nobodyさん02/08/11 12:53ID:???
flock使えるならflockにしとけよ!!!
0263nobodyさん02/08/11 13:45ID:???
flockよりKENTが優れていることが証明されました!!!
0264nobodyさん02/08/11 13:46ID:???
どこで?
0265KENT02/08/11 15:40ID:???
flockってカエルだよね?
0266 02/08/11 15:50ID:???
おはロックが有効な鯖ってあるの?
0267nobodyさん02/08/11 19:41ID:???
>>228
だから初めにflock効いてるのか調べてと言ってるのに
空振りしてるんだよ、それ
他のファイル編集部分は時間的にロック無しでも動いてるだけだよ多分
0268nobodyさん02/08/11 21:39ID:???
「多分」って便利な言葉
俺は断言してないよ、忙しかったしよって感じ
0269nobodyさん02/08/14 01:12ID:???
http://www.kent-web.com/support/wforum.cgi?mode=allread&no=3986&page=0

排他処理とはちょっとズレるかもしれないが、これは立派にシステム上に矛盾が起きてるんだから、"バグ"ではないにしろ、立派な不具合だよな…
この不具合って、そんなに難しいことなのかな…
あたりまえのように、こういうのは想定しないかな?
Kentのスクリプトって、こういうところが馬鹿だよね。
0270nobodyさん02/08/14 01:45ID:7AoVgCGe
http://homepage1.nifty.com/glass/tom_neko/web/web_04.html#lockall
このまとめてロックっていいんですか?
0271nobodyさん02/08/14 02:02ID:???
>>270
      ,一-、
     / ̄ l |   / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
    ■■-っ < んな こたーない
    ´∀`/    \__________
   __/|Y/\.
 Ё|__ | /  |
     | У..  |
0272nobodyさん02/08/14 02:05ID:7AoVgCGe
やっぱだめなんですか
0273nobodyさん02/08/14 02:14ID:7AoVgCGe
他にいい方法はありませんか?
0274nobodyさん02/08/14 04:31ID:???
ヅラを強力ロック
0275nobodyさん02/08/14 20:00ID:DbQN4DsP
監獄ロック
0276nobodyさん02/09/14 03:01ID:???
慎吾ママの
0277nobodyさん02/10/01 08:47ID:OVvB7u9F
http://kagino110.hp.infoseek.co.jp/sub18.htm
強力なロックだ
0278nobodyさん02/10/01 14:48ID:???
>>277
ううむ、強力すぎてアクセスさえもできないよ!
0279名無しさん@お腹いっぱい。02/10/01 16:34ID:???
>>278
漏れは開きすぎちゃったよ。windows再起動した。
皆気をつけろよ。中のどれか開いたりしたら、国際電話だぞ。

0280名無しさん@お腹いっぱい。02/10/04 08:00ID:???
ム板の「Perlについての質問箱」がruby基地外によって潰されました。
心ある人は、rubyスレにお礼参りしてください。
0281nobodyさん02/10/08 18:16ID:???
>>277
ちょっとワラタ
0282nobodyさん02/10/11 23:24ID:0pBUR/gh
read.cgiのファイルロック。これ最強
0283nobodyさん02/10/12 00:02ID:???
>>282
どういうロックやってるの? 知らないから教えてくれ。
0284nobodyさん02/10/15 14:15ID:???
ロックなんかしてないよ
2chの負荷でロックなんかしたら使い物にならん
壊れてたら読み直せばすむことだし
0285nobodyさん02/10/15 18:19ID:jOp8uFKz
bbs.cgiはどうやってるの?
0286nobodyさん02/10/16 11:23ID:???
日時とスレッドキーなんかを含めたファイル名で
一時ファイルを作って書き込み終わったら
subject.txtにリネーム
renameのアトミック性に頼ってるわけだな
datはふつうにflockしてるだけ
0287nobodyさん02/10/22 13:32ID:???
わたし 思う。
ロック機能作る。
理論的 このスクリプト完璧。
でも どうテストする。
アルバイト100人雇う。
100人いっせいにアクセスする。
そんな 手間かけられない。 どうする。
2ちゃんねるに晒す。 それ怖い。 どうする。
0288 02/10/22 16:25ID:???

・ 実験しないで本番に使う。
・ 覚悟して晒す。
・ 一年生になって友達100人つくる。
0289nobodyさん02/10/22 16:39ID:???
>>287
不覚藁
0290nobodyさん02/10/22 17:09ID:???
>>287
100 スレッド立ててアクセスしまくるにきまっとろーが。
0291nobodyさん02/10/27 19:23ID:zFNcoqUs
>>185
別人ですが、読み込んだものを加工してまた書き込む場合には
読み込むときにもロックが必要なんですね?
単に読み込んで、例えば表示したいだけで
加工もしない場合は必要ないんですよね。
0292nobodyさん02/10/27 21:19ID:???
ログ更新中に読み出したらおかしな内容になってしまう。ロックは必要。
0293nobodyさん02/10/27 22:41ID:???
テストスクリプトはlock握って数十秒眠るようにするわけだ。勿論タイムアウト値の調整は必要だ。
そうすりゃ一人でもテストできるだろ。
0294nobodyさん02/10/28 01:48ID:???
>>292
表示がおかしかったら読み直してもらうという
アプローチもありうる(read.cgiとか)。
0295nobodyさん02/10/29 01:24ID:3RRgraL5
flockについて、説明として例えば

flock(XX, 2)
書込中だから書込読込ロック、あとから来たら待つ。

とあるのですが、待つってどのくらい待つことが出来るのでしょう…?
上限や目安みたいなものはあるのでしょうか?
0296nobodyさん02/10/29 01:40ID:???
>>295
めっちゃ、待つでぇ
0297 ◆hMJAPH9PWA 02/10/29 09:26ID:???
>>295
実行者が我慢できなくなって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:5Ci8Aq1y
んむ・・・。
0302perlお勉強ちゅー02/11/29 01:12ID:vd7dmowT
>>299
こんな感じかな、

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:???
↑ open の戻り値チェックしてなかった。スマソ
0304私も勉強中02/11/29 17:19ID:???
close (OUT);
から
rename ("$process.tmp","data.txt");
までの間に、他のプロセスが open (OUT,">$process.tmp") を
実行してしまい、$process.tmpが空になる可能性がある。

※open (OUT,">$process.tmp")した瞬間
$process.tmpのファイルサイズが0になるので、
次の flock (OUT,2) で止めても手後れ。

そんな気がするが、どうだろうか。
030530402/11/29 17:25ID:???
ごめん、間違えた。
tmpファイルの名前を毎回変えれば大丈夫か。
0306nobodyさん02/11/29 19:16ID:???
>>302
普通に、だめだね。
たとえば、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:???
>>304 さん >>306 さん
ご解説して下さってありがとうございます。
close しなければ rename できないと勝手に
思い込んでいました。(やってみたらできました)
close したときに flock が解除されるのなら
rename 後に close しとけば別プロセスに割り
込まれることが減り、少しはましになるかな。
0308nobodyさん02/11/30 15:54ID:???
>>307
> 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:???
open (LOCK,"lock");
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を使ったファイルロックと言っていいのかどうか分からないが。
0310nobodyさん02/12/01 00:55ID:???
>>309
flock は、とりあえず >>1 の条件に反するので0点ってとこかな?
0311perlお勉強ちゅー02/12/01 14:43ID:???
>>308
またもやありがとうございます。
rename 後の close を Windows2000 で試したところ、
ご指摘のとおりエラーになりました。

open してから flock するまでに間が空くのがいけないと思い、
今度はフラグを立てるタイプを考えてみましたが、
フラグが立ってるか判別するまでに間が空く・・・
私には解決が難しいので人のソースでもっと勉強してみます。
0312cron02/12/02 11:25ID:YojCbNB7
ちょっと教えてほしいんだけど。。

Perlでロックしていてもcronでroot権限でrenameしてしまえるみたいなんだけど
Perlで複数のユーザーがどんどん書き加えていくファイルを何分か置きに
root権限で実行したい場合 問題の起こらない良い方法はありますか?
0313nobodyさん02/12/02 11:37ID:???
>>312
rootで何をしたいのか?
0314cron02/12/02 13:01ID:YojCbNB7
rootでしか実行できないコマンドを実行させるのに
そのコマンドのオプションはCGIで書き込ませたいのです。

0315nobodyさん02/12/02 14:26ID:Vw2f1Ru9
>>314
ネタだよなぁぁぁぁ、頼むからネタだと言ってくれー
0316cron02/12/02 15:25ID:YojCbNB7
なんで?おかしかった?ちゃんと教えてください
0317☆☆☆☆☆02/12/02 15:47ID:Z6bI7Cqn
http://alink3.uic.to/user/ranran2.html
0318nobodyさん02/12/02 22:12ID:???
オプティミスティック
オプティミスティック
オプティミスティック
ペシミスティック
ペシミスティック
ペシミスティック

あー、言いにくい
0319nobodyさん02/12/06 00:00ID:???
>>316
あのさあ、rootって管理人のことだろ?
どこの鯖缶が赤の他人にroot権限使わせるってのよ。
やるんなら自鯖立ててやんなよ。
0320Perlお勉強ちゅー02/12/06 01:16ID:???
アトミックというのと、入出力の処理全体を包み込むというのが
ファイルの排他処理のキーワードらしいとわかってきました。(つもり)
フラグにするものがアトミックというのは、例えれば、
一組のトランプからはクラブの 1 は 1 枚しか引けないからこそ
目印になるということかな。親元になければ誰もカードを取れないものね。

気になったのは、アトミックがいくつかの使われ方をしている事で、
1 : 現在の ファイル I/O では HDD への読み書きは物理的には一つしかできないことに依存してフラグを立てる。
  (HDD の複数ヘッドがばらばらに動いてたらこわいです。)
2 : Perl 上で処理全体をアトミックにと言う場合は、「読み」「処理」「書き」を
   「1」に依存して、他人(他プロセス)に口をはさませずに行う。
・・・って感じかな。
# 見当違いでしたらつつしんで怒られます。とほ。
# お勉強中途報告でスマソ。
0321cron02/12/08 07:08ID:tHo7Ijtw
>>319
root権限で当然、自サバでするんだよ
cronのことしらないの?
0322nobodyさん02/12/08 08:24ID:???
>>321
cronで動かすプログラムとWebプログラムでのファイルのロックが問題なの?
普通のファイルロックと同じようにやればいいじゃん。
032331902/12/08 11:44ID:???
>>321
自鯖でやるなんて一言も言わなかったじゃないか。
そもそも、自分が鯖缶だとも言ってない。

cronでCGI動かすようにすれば? んで、CGIの方でロックをきちんとすればいい。
0324nobodyさん02/12/08 11:44ID:???
やればいいじゃん。
0325nobodyさん02/12/08 12:07ID:???
>>323
cronでCGI動かすなんてアホな発想はどこから出てくるんだ?
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
open(ABC "<$hoge") || &error("error");
とかよくやりますが
close(ABC);
閉じるときも
close(ABC) || &error("error");
とやるべきでしょうか?
closeに失敗することあるんでしょうか?
0330nobodyさん03/01/17 12:29ID:+SxK8G04
>>329
非常にいい質問だね。
さ、誰か答えてやんなさい。
0331nobodyさん03/01/17 13:58ID:???
while (!close(ABC)) {}
0332nobodyさん03/01/18 00:49ID:???
perl -e 'close(STDIN); close(STDIN) || die $!'
それがどうファイルロックと関係あるのかと
0333nobodyさん03/01/18 14:04ID:???
ファイルロックしている最中にcloseに失敗してエラー処理をせずに
処理が終了されて、ロック解除できずロックファイルが残る場合。
0334nobodyさん03/01/18 17:36ID:???
Apacheのアクセスログなんか尋常じゃないほどの書き込みがあるが
どうして上手くいっているのだろうか?
0335nobodyさん03/01/18 18:30ID:???
>>334
O_APPEND
0336nobodyさん03/01/18 20:35ID:???
>>333
エラー処理の中にバグを入れるのは本末転倒だろうが。
0337nobodyさん03/01/18 20:51ID:???
>>335
ファイルの追加書き込みって上手く使うとflockないシステムでも上手くロックをかけれるかも
0338nobodyさん03/01/19 23:58ID:???
>>337
ロックじゃねーよ。
0339世直し一揆03/01/30 10:23ID:EZ4VgkoJ
<血液型A型の一般的な特徴>(見せかけの優しさ・もっともらしさ(偽善)に騙され
るな!)
●とにかく気が小さい(神経質、臆病、二言目には「世間」、了見が狭い)
●他人に異常に干渉し、しかも好戦的・ファイト満々(キモイ、自己中心)
●自尊心が異常に強く、自分が馬鹿にされると怒るくせに平気で他人を馬鹿にしようと
する(ただし、相手を表面的・形式的にしか判断できず(早合点・誤解の名人)、実際に
はたいてい、内面的・実質的に負けている)
●本音は、ものすごく幼稚で倫理意識が異常に低い(人にばれさえしなければOK)
●「常識、常識」と口うるさいが、実はA型の常識はピントがズレまくっている(日本
の常識は世界の非常識)
●権力、強者(警察、暴走族…etc)に弱く、弱者には威張り散らす(強い者に弱く
、弱い者には強い)
●あら探しだけは名人級(例え10の長所があってもほめることをせず、たった1つの短所を見つけてはけなす)
●基本的に悲観主義でマイナス思考に支配されているため性格がうっとうしい(根暗)
●一人では何もできない(群れでしか行動できないヘタレ)
●少数派の異質、異文化を排斥する(差別主義者、狭量)
●集団によるいじめのパイオニア&天才(陰湿&陰険)
●悪口、陰口が大好き(A型が3人寄れば他人の悪口、裏表が激しい)
●他人からどう見られているか、人の目を異常に気にする(「世間体命」、「〜みたい
」とよく言う)
●自分の感情をうまく表現できず、コミュニケーション能力に乏しい(同じことを何度
も言ってキモイ)
●表面上意気投合しているようでも、腹は各自バラバラで融通が利かず、頑固(本当は
個性・アク強い)
●人を信じられず、疑い深い(自分自身裏表が激しいため、他人に対してもそう思う)
●自ら好んでストイックな生活をし、ストレスを溜めておきながら、他人に猛烈に嫉妬
する(不合理な馬鹿)
●執念深く、粘着でしつこい(「一生恨みます」タイプ)
●自分に甘く他人に厳しい(自分のことは棚に上げてまず他人を責める。しかも冷酷)
●男は、女々しいあるいは女の腐ったみたいな考えのやつが多い(例:「俺のほうが男
前やのに、なんでや!(あの野郎の足を引っ張ってやる!!)」)
0340nobodyさん03/01/30 12:26ID:RKDiglA0
最近運用してるページでロックがよく残る、書き込みファイルがロックしてるにもかかわらず
壊れるという現象が頻発して困ります。
なにか他のいい方法を探しているのですが
書き込み待ちテンプを作るやり方があると聞いたのですが
教えてください。
0341nobodyさん03/01/30 13:08ID:???
>>340
マジレス
お前のロックの仕方が変なだけ
0342nobodyさん03/01/31 04:05ID:QdG4FrQH
画像貼り付け掲示板なのですが
どのようにロックかけるのがのぞましいのでしょうか?
0343nobodyさん03/01/31 07:27ID:K4VaGHSu
いいサイトだ♪http://homepage3.nifty.com/digikei/ten.html♪
0344nobodyさん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:???
よくチャックがあけっばなしと言われます
■ このスレッドは過去ログ倉庫に格納されています