1 名前:nobodyさん [02/06/23 10:18 ID:eY2l+Gw1] どんな環境でも使えて、軽くて、頑丈なロックを考えようじゃありません
152 名前:nobodyさん mailto:sage [02/07/10 18:38 ID:???] >>151 MySQL が BerkleyDB の機能を使ってトランザクションを実現 しているくらいなのに、lock やってないわけなかろ。いつの version の話してるの? www.sleepycat.com/docs/reftoc.html www.sleepycat.com/docs/ref/lock/intro.html 見て出直してこい。ちなみにこの document は 4.0.14 のだけど、 3.x のころからしっかり lock subsystem がある。
153 名前:nobodyさん mailto:sage [02/07/10 21:53 ID:???] >>152 OS標準で入ってるつーと 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でサポートされてる部分しか使えねーはずだが。
154 名前:nobodyさん mailto:sage [02/07/11 02:02 ID:???] >>153 search.cpan.org/search?dist=BerkeleyDB 使えば? あと、FreeBSD では完全に標準な状態ではたしかにそうだけど、ふつう ports で 3.x が入ってくるし、Debian でも完全に標準では 2.x でふつう 3.x、RedHat では完全に標準で 3.x が入る
155 名前:nobodyさん mailto:sage [02/07/11 04:50 ID:???] どうせロッキングするならクリティカルな場合も考えないといけないし、 それなら車輪の再発明は止めて最初からDBMSを使うべきというのは 反論しようのない正論。しかも、リソースのありかまで教えてくれているし。 ただ、こういう極めて的確な回答があると、この手のスレはつまらなくなるね…。
156 名前:nobodyさん mailto:sage [02/07/11 06:50 ID:???] >>155 それでも、ダラダラとレスしてる奴等がいるところを見るとこの板のレベルの低さが解るね
157 名前:nobodyさん mailto:sage [02/07/11 09:23 ID:???] また釣れた(・∀・)クスクス
158 名前:nobodyさん mailto:sage [02/07/11 11:11 ID:???] DBMSやflock等の飛び道具使えないときにどうするかというパズルじゃないの?
159 名前:nobodyさん mailto:sage [02/07/11 16:21 ID:???] つかperlのflockてatomicじゃないだろ
160 名前:nobodyさん mailto:sage [02/07/11 21:02 ID:???] flock(2)使うときのflockはアトミックでしょ。 lockfでエミュレートしてるのはヤヴァイの?
161 名前:nobodyさん mailto:age [02/07/12 18:11 ID:???] # 初心者スレから誘導されてきました。 # 排他処理をしたいです。 # ローカル環境(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);
162 名前:nobodyさん mailto:sage [02/07/12 19:10 ID:???] >>161 ディレクトリに書き込み権限がない。 既にロックされている(./lockfileが存在する)。 のどちらか。 &create_lock("./lockfile", 5); と &remove_lock($dir_lock); のファイル名が…
163 名前:nobodyさん mailto:sage [02/07/12 19:38 ID:???] >>162 ご指摘ありがとうございます。(;ワ;) 今夜さっそくディレクトリの書き込み権限のチェックをしてみます。 えーと、下の $dir_lock は貼り付け時に直し忘れました(^^;) 混乱させてしまったようで、すみません。 あとでまた結果報告しにきます。
164 名前:161 mailto:sage [02/07/13 07:51 ID:???] できました〜! >>162 さん、感謝です。助かりました。
165 名前:nobodyさん [02/07/18 03:33 ID:???] 叩かれに来ました。 open(OUT, "+< outfile.txt"); flock(OUT, 2); truncate(OUT, 0); seek(OUT, 0, 0); print OUT "........"; close(OUT); の欠点を教えてください。 お願いします。
166 名前:nobodyさん mailto:sage [02/07/18 05:55 ID:???] >>165 いいんじゃないの?それでも別に。
167 名前:nobodyさん mailto:sage [02/07/18 13:34 ID:???] ........吐くだけならロックしなくて良いじゃん
168 名前:nobodyさん mailto:sage [02/07/18 14:33 ID:???] >>167 じゃあ、二つのプロセスが同時に同じファイルに対して吐きにいったら どうなる?
169 名前:nobodyさん mailto:sage [02/07/18 14:56 ID:???] open(OUT, "+< outfile.txt"); 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)
170 名前:nobodyさん mailto:sage [02/07/18 15:36 ID:???] どうもならないよ、定数吐き出すだけでしょ? 正確にはsyswriteするか$|=1してバッファ使わない様にした方が良いけど
171 名前:nobodyさん mailto:sage [02/07/18 15:38 ID:???] truncateしなくて良いじゃん変数じゃ無いのに 前提が変なのに何をどうしたいのやら
172 名前:nobodyさん mailto:sage [02/07/18 15:41 ID:???] どこに定数って書いてるんだ?
173 名前:fusianasan mailto:age [02/07/18 16:45 ID:???] >>172 だれに言ってるんだ? わたしの記憶が確かなら>>170 に定数って書いてるYO!
174 名前:nobodyさん mailto:sage [02/07/18 17:11 ID:???] この棘々しい会話の流れ ( > v<)ノ タマンネー♪
175 名前:nobodyさん mailto:sage [02/07/18 17:30 ID:???] 定数だろうが変数だろうが返り値だろうが関係ないわけですが
176 名前:nobodyさん mailto:sage [02/07/18 17:34 ID:???] >>175 は? 何言いたいのおたく? もうちょっと日本語の文章力付けなさいよ
177 名前:nobodyさん mailto:sage [02/07/18 17:42 ID:???] みんなあまのじゃくさん♪
178 名前:nobodyさん mailto:sage [02/07/18 19:10 ID:???] すんげー荒れてるw
179 名前:nobodyさん mailto:sage [02/07/18 23:34 ID:???] この程度で荒れてるって言うのか。
180 名前:nobodyさん mailto:sage [02/07/18 23:43 ID:???] 荒れてるというよりみんなすさんでるな。 漢字で書いたら一緒だけど。 ま、もう当分この板はこんな調子でしょ・・・。
181 名前:nobodyさん mailto:sage [02/07/19 01:05 ID:???] この板ってほんと殺伐系だね。馴れ合い一切なし。さっぱりしてて気持ちいいけどね。
182 名前:nobodyさん mailto:sage [02/07/19 01:29 ID:???] >>165 いろいろなレスがあるけど、flockつかえるなら、それでいいんだよ。 初心者板でそう言い返してこい。
183 名前:nobodyさん mailto:hoge [02/07/19 02:38 ID:???] 突然ですが、読むだけのオープンでもflockが必要なの? 他のプロセスとの関係とかあります?
184 名前:nobodyさん mailto:sage [02/07/19 02:45 ID:???] >>165 >>1 参照。 どんな環境でもつかえてっていうのが、このスレの主題。 flockは環境によってはつかえない。 flockつかえるなら、それでいい。
185 名前:行番号でるかな mailto:sage [02/07/19 03:00 ID:???] >>183 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の内容はどれか一つの プロセスの内容しか反映されて居ないだろう。
186 名前:183 mailto:sage [02/07/19 03:17 ID:???] なるほど、了解しました。 どこかのサイトに読み込みオープンでもflockすべきだと 書いてあったのが気になっていたんですが、 そういう場合のことだったんですね。 ありがとうございました。
187 名前:nobodyさん mailto:sage [02/07/19 14:05 ID:???] ファイルロックなんでも相談室っぽい雰囲気になりそうだ
188 名前:nobodyさん [02/07/19 15:23 ID:H65klWUw] www.din.or.jp/~ohzaki/perl.htm#File_Lock これじゃだめか?
189 名前:nobodyさん mailto:sage [02/07/19 15:44 ID:???] timeが全く同じだと、通常のrename式と同じ問題が生じる。 まあ、可能性ははるかに低くなると思うが。
190 名前:nobodyさん mailto:sage [02/07/19 15:48 ID:???] >>189 ???????????????????????????????????????????????????
191 名前:nobodyさん [02/07/19 19:14 ID:g9uMB3Mk] >>189 同じtimeでも唯一のプロセスしかロックできないから大丈夫でない? 1秒内にロックを解除しないままプロセスが死んだ時ってこと?
192 名前:nobodyさん mailto:??? [02/07/20 21:32 ID:???] 2chはflockか?
193 名前:nobodyさん [02/07/25 16:40 ID:Ong5dr5a] 結局、実際の書き込みを、 1.ユニークなファイル名を作り書き込み。 2.指定のファイル名にrename にしときなさいってこった。
194 名前:nobodyさん mailto:sage [02/07/25 17:54 ID:???] >>193 rename時に衝突することもあるってこった。
195 名前:nobodyさん mailto:sage [02/07/26 01:04 ID:???] ファイルロック完全にやって50点。 書き込み中のプロセス事故死に対応して100点。
196 名前:nobodyさん mailto:age [02/07/26 02:18 ID:???] >>195 それでは認識が甘いな。
197 名前:nobodyさん mailto:age [02/07/26 03:55 ID:???] &unlock if($lockkey); sub unlock{ 省略 } この構文の意味がわからんから教えてくれ unlock関数とif文が何で一緒になってるんだ?
198 名前:nobodyさん mailto:sage [02/07/26 05:36 ID:???] 教えてくれ、だってさ教えてくれ!! ちょっと聞いた奥さん教えてくれ! ぷぷぷ
199 名前: mailto:sage [02/07/26 09:01 ID:???] >>197 はマルチポスト
200 名前:nobodyさん mailto:age [02/07/26 11:19 ID:???] ファイルロックって書き込み処理のときだけすればいいんですか? 読み込み処理のときにはしなくてもいいんですか?
201 名前:nobodyさん mailto:age [02/07/26 11:27 ID:???] >>192 2ちゃんはflockでした
202 名前:nobodyさん [02/07/26 13:35 ID:NvB7dZaP] &unlock if($lockkey); = if($lockkey) { &unlock; }
203 名前:nobodyさん mailto:sage [02/07/26 13:45 ID:???] >>197 && >>202 ファイルロックとは関係ないぞ。 Perl初心者スレへ。
204 名前:nobodyさん mailto:sage [02/07/28 16:44 ID:???] >>191 それでもタイムアウトまでは待つのでは? あ、正常な処理中にタイムアウトを超えてしまった場合が問題なのかな? 完璧を追求するのなら。
205 名前:nobodyさん mailto:age [02/07/29 14:41 ID:???] あげてわるいか!
206 名前:nobodyさん mailto:sage [02/07/29 14:47 ID:???] わるいっつったらどうするよ?
207 名前:nobodyさん mailto:age [02/07/29 15:10 ID:???] >>206 あげたもんはさがるまで待つしかしょーがねーだろ?って開き直るよ。
208 名前:nobodyさん mailto: [02/07/29 15:15 ID:???] homepage1.nifty.com/glass/tom_neko/web/web_04.html のページでロックの仕方が紹介されていたので使わせてもらおうと思いました。 で、「古いロックファイル(ディレクトリ)の削除」の項目にある、 $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ちゃんねるみたいな同時アクセスが凄い場所でない限り。
209 名前:nobodyさん mailto:sage [02/07/29 15:21 ID:???] >>207 別にわるかねぇよ。
210 名前:nobodyさん mailto:age [02/07/29 15:24 ID:???] >>207 バグもあるけどキミんとこのアクセス数ならOK。
211 名前:nobodyさん mailto:sage [02/07/29 15:36 ID:???] >>210 どういう意味なんだ?
212 名前:nobodyさん [02/07/29 15:55 ID:yLhb3gGL] どこからダウンロードしたのか忘れたんだけど、 使ってるカウンター(Perl)見たら、 ロックファイル作成 ↓ ファイル読み込み ↓ ロックファイル消す ↓ カウントUP ↓ ロックファイル作成 ↓ ファイルに書き出し ↓ ロックファイル消す といった流れになってたんだけど、初めのファイル読み込みの時にもロックは必要なの?
213 名前:nobodyさん mailto:sage [02/07/29 16:25 ID:???] >>219 とんでもねぇロックの仕方だな
214 名前:nobodyさん mailto:sage [02/07/29 16:27 ID:???] >>219 はとんでもないロックを出さなければいけない。
215 名前:nobodyさん mailto:sage [02/07/29 16:32 ID:???] 219に期待sage
216 名前:nobodyさん mailto:sage [02/07/29 17:26 ID:???] >>219 はロッカー♪
217 名前:nobodyさん mailto:sage [02/07/29 17:33 ID:???] >>219 凄い。そんなアルゴリズムがあったのか。
218 名前:nobodyさん mailto:sage [02/07/29 17:35 ID:???] >>219 ある意味で、とんでもないな。
219 名前: ◆JAPH9PWA mailto:sage [02/07/29 21:21 ID:???] unless(`ps` =~ /\Q$0\E/) { # ロック権を取得したので処理をする }
220 名前:nobodyさん mailto:sage [02/07/29 22:11 ID:???] >>219 \Qと\Eの意味知らんけど、確かにとんでもないな
221 名前:nobodyさん mailto:sage [02/07/29 22:13 ID:???] Windowsでうごかねぇよ。
222 名前:nobodyさん mailto:sage [02/07/29 22:15 ID:???] 他のプロセスを全てkillする排他制御はどうか
223 名前:nobodyさん mailto:sage [02/07/29 22:17 ID:???] >>222 最強だな、うん
224 名前:nobodyさん mailto:sage [02/07/30 03:13 ID:???] >>223 なんで最強なんだ? suEXEC ならどうする?
225 名前:nobodyさん mailto:sage [02/07/30 09:03 ID:???] httpdから何から、「全て」killするからでしょ。root限定で
226 名前:nobodyさん mailto:sage [02/07/30 09:52 ID:???] そんな真面目に考えなくても
227 名前:nobodyさん mailto:sage [02/07/30 11:37 ID:???] 木村ロック
228 名前:nobodyさん [02/07/31 23:34 ID:EOzgSn6U] 書き込み中にタイムアウトになるとログが壊れます?
229 名前:nobodyさん [02/08/01 02:00 ID:DTOpJumx] >>228 に便乗 @open直後 Aprint直後 Bclose A、A〜Bでしょうか? でもopenでクリティカルな場合に吹っ飛ぶこと考えると…@?
230 名前:nobodyさん mailto:sage [02/08/01 03:58 ID:???] >>228 サーバの正常なタイムアウトなら、書き込みのシステムコールの 途中で止まったりしないでしょう。数回に分けて書き込んでたら、 止まるけど。サーバの容量制限に引っ掛かって止まる事もあるし。 >229 書き込むときに上書き(>)で開くと内容が消えるので、その直後に 止まったらアウト。 どうしてもログを守るんだったら、かならずtempファイルに書き 出して、書き込み成功を確認した後にrenameすることが必要。 ファイルサイズを計ってサイズが異様に小さいときは失敗だし、 内容をチェックすれば完璧。 これならrenameの瞬間に電源が切れるか、HDDがクラッシュする くらいの事がなければ、壊れないはず。(バグは除く) どのみち定期的なバックアップは必要かもね。
231 名前:229 mailto:sage [02/08/01 13:35 ID:???] >>230 thnx 参考になりますた
232 名前:193 [02/08/01 19:06 ID:W9oFKOXJ] >>194 だから〜。 処理ロックのファイルロックは当然かけておいて、 書き込み時はユニークファイル名に書き出してrename ってこったよ。
233 名前:nobodyさん mailto:sage [02/08/02 01:01 ID:???] >>232 アマちゃんですね。
234 名前:nobodyさん mailto:sage [02/08/03 18:57 ID:???] www.google.co.jp/search?hl=ja&inlang=ja&ie=Shift_JIS&as_qdr=all&q=site%3A2ch.net+perl&lr= >>1-233 この調子でがんばれ糞ども
235 名前:228 [02/08/03 20:27 ID:npWjw1lc] 230さま たまにログファイルが途中でぶち切れちゃうんです ファイルアップありだから でかいファイルをアップロードした時に 途中でタイムアウトするのかと思ったんですが そうでもないんですね・・・ 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使えない鯖なんでしょうか? 他に原因は考えられます?
236 名前:nobodyさん mailto:sage [02/08/03 23:45 ID:???] >>235 でかいファイルを全部配列に入れるのは大問題だ
237 名前:228 [02/08/04 07:59 ID:xc+iopog] >236 50件ずつにログを区切ってるんで 読み込んでるのは 書き込み50件分のデータです スレッドのタイトル一覧も表示しないといけないし・・・
238 名前:228 [02/08/04 08:03 ID:xc+iopog] やっぱ flockが使えないんでしょうか? それかtell(DB)の値がおかしくなることがあるのかな?
239 名前:nobodyさん mailto:sage [02/08/04 12:11 ID:???] >>235 > seek(DB, 0, 0); > print DB @lines; > truncate(DB, tell(DB)); 先頭にseekした後に、truncate(FH, tell(FH)) したら当然ファイルサイズ0に なるわけだが。
240 名前:230 mailto:sage [02/08/04 12:57 ID:???] データが大きくないとしても、my @lines=<DB>が失敗してるのかも。 my @lines=<DB> or &error('読み込みエラー'); としてみては? 読み込んだ大きなファイルの方にメモリを食われてるのかもしれず。 システムコール(ここではファイル操作)は常に失敗の可能性を考えて おいたほうがいいかと。flockやprintもね。
241 名前:nobodyさん mailto:sage [02/08/04 13:14 ID:???] >>235 もうちょっと問題切り分けた方が良いよ マルチパートだと思うんだけど、変なモジュールを使って データ千切れちゃってるとか。 Niftyはflock空振りサーバの代名詞だけど大丈夫? 適当にsleepしてウェイトかけながらテストするとか シグナル関係全部無視するとか 基本的に共用ならサーバからkillされる様な使い方は 間違ってると思うよ もし自分のなら、さっさとコネクション切ってじっくりと作業すれば 良いだけなんだけど サーバのBBSとかFAQは読んでる? >>239 それは print 〜 が有るから問題無い と言う事で、一応。
242 名前:239 mailto:sage [02/08/04 14:38 ID:???] >>241 正直、スマンカッタ。
243 名前:nobodyさん mailto:sage [02/08/04 15:21 ID:???] で、なにが最強なの?
244 名前:228 [02/08/04 21:59 ID:etatASlj] レスありがとうございます 最初から書いとくべきだったんですが 説明を付け足すと 2chタイプの掲示板なんです でログファイルへの書き込みはこの部分だけです カウンターなんかも同じ方法で書き込みしてるんですが それは飛んだことないんです で、ログファイルへの書き込みが処理の最後の方なので 遅い回線でファイルアップした時にデータを送るのに 時間がかかり途中でCGIが止まる事があるのかな? と考えてたのです(最後の方の処理のログファイルが影響受けやすいと) でも、どういう条件でログが消えるのかは特定できてません スレッド50件記録のうちの途中(全部じゃないです。例えば36件目とか)で 消えてしまいます(メッセージが途中までしかなかったり)・・・ (レスは別ファイルなのですが、そっちは消えません) >読み込んだ大きなファイルの方にメモリを食われてるのかもしれず。 そういう制限もあるんですね試してみます >もうちょっと問題切り分けた方が良いよ でも、書き込みしてるのこの部分だけなんですよ やっぱflockが使えなくて 他のプロセスの書き込み中のデータを読み込んでるとログが途中で消えますよね? でも、カウンターは消えないんですよ・・・ (それともそのうち消えるんでしょうか?ファイルサイズが小さいから確率が低いだけ?) >サーバのBBSとかFAQは読んでる? すいません、その辺、勉強してきます
245 名前:nobodyさん mailto:sage [02/08/04 22:48 ID:???] >>244 一度flock以外のロックで試してみれば? こういうのが問題を切り分けるって事じゃないのか。
246 名前:230 mailto:sage [02/08/05 01:30 ID:???] データのどこで切れるかが重要。 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ファイル式にす るしか無いけど、まずは上記の対策してから。
247 名前:228 [02/08/06 00:52 ID:eY1Nkha6] my @lines=<DB> || &error('読み込みエラー'); にしたら 最初の一行しか読まないんですが・・ すいません・・・
248 名前:nobodyさん mailto:sage [02/08/06 01:13 ID:???] 評価順位って知ってる? (@lines=<DB>) その他力本願ぶりじゃ先は真っ暗っぽいね
249 名前:228 [02/08/06 01:14 ID:HdiBMgeW] or にしたら ちゃんと動きました or と || とは違うんですか? はぁ・・
250 名前:228 [02/08/06 01:29 ID:AoKqt/pr] おお、わかりました ありがとうございます
251 名前:nobodyさん mailto:sage [02/08/06 06:51 ID:???] >>248 ハァーーーーーーーー 眠たい
252 名前: mailto: [02/08/06 09:00 ID:???] >>251 何が眠たいんだ? my (@lines=<DB>) || &error('読み込みエラー'); で動いてるんだが、向学の為に教えて欲しい