- ベストアンサー
【ruby】flockで掛けたロックを参照したい
- 複数プロセス間で、一つのファイルに対して読み書きしたいです。その際、ファイルへの書き込み中は、ファイルの読み込みを抑止したいです。また、読み込みの処理はファイルのロックを参照するだけで、ファイルへのロックは掛けない様にしたいです。
- プログラム1はキーボードからの入力があるまで、ファイルをロックする方法を実装しました。
- プログラム2でファイルがロックされているか状態を取得しようとするとエラーが出てしまいます。Unixレンタルサーバ(FreeBSD)環境での対処方法を教えてください。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
これはRubyというより、Unixの問題ですね。 flockのロックはファイル全体のロックで、fcntlのロックはファイルの中のl_startバイト目からl_lenバイトの領域に対するロックですので、全く別のものです。両方同じ方式を使う必要があります。 flockを使うとすると、 #!/usr/local/bin/ruby file='./hoge.txt' f=open(file,'r+') ret=f.flock(File::LOCK_EX|File::LOCK_NB) if ret puts "ロック成功" STDOUT.write 'Hit any key' STDIN.gets.chomp else puts "ロック失敗" end #!/usr/local/bin/ruby file='./hoge.txt' f=open(file,'r') ret=f.flock(File::LOCK_SH|File::LOCK_NB) if ret f.flock(File::LOCK_UN) puts "ロックされていなかった" else puts "ロックされていた" end fcntlでロックするなら、arg="" じゃなくて、man 2 fcntl を見てstruct flockの内容をセットしたものをargとして渡さないといけません。
その他の回答 (1)
- notnot
- ベストアンサー率47% (4900/10358)
排他ロック(LOCK_EX)と共有ロック(LOCK_SH)については理解されたようですね。 読み取りに関係なく書きたいのであれば、読み取り側でロックせずに読めばいいです。質問では「排他ロックがかかっているかどうか知りたい」ということのようですが、何のために知りたいのですか?
お礼
notnotsaさん、ご回答ありがとうございます。 >読み取りに関係なく書きたいのであれば、読み取り側でロックせずに読めばいいです。質問では「排他ロックがかかっているかどうか知りたい」ということのようですが、何のために知りたいのですか? 最初に質問した時は、 『他者が書き込み中には書き込みも読み込みはできない』 を実現したいと考えていて、『他者が読み込み中の書き込み』についてはあまり考えていませんでした。 他者が読み込み中でも、他者が読み込んでいる時点のデータを保障しつつ、書き込みが可能って仕様が好ましいのですが、これはファイルのロック機構でなんとかなるものでは無いので、「排他ロックがかかっているかどうか」についは、もうどうでもいいです。 結局、ファイルのロックは使わずに、先ずはテンプファイルに書き込み、 書き込み終了と共にrenameって方法にしました。
お礼
notnotさん、ご回答ありがとうございます。 File::LOCK_SHは、既にFile::LOCK_SHで掛けられたロックに対しては ロックを掛けられるが、File::LOCK_EXで掛けられたロックに対してはロックが掛けられないんですね。 これで、読み込み同士は干渉せずに、書き込み中は読み込みを抑止が実現できるのは解ったのですが、 色々試してみると、読み込みで掛けたロック(File::LOCK_SH)中は、書き込みでFile::LOCK_EXのロックが掛かられませんでした。 他プロセスが読み込み中でも、書き込みは出来るのが望ましいのですが、これを実現するのは、ファイルのロックを利用するだけでは無理って事なんですね。