From: Mauricio Fernandez Date: 2006-08-14T18:58:34+09:00 Subject: Re: How do you use flock and clean up lock files? On Mon, Aug 14, 2006 at 12:57:09PM +0900, John Carter wrote: > On Mon, 14 Aug 2006, Francis Cianfrocca wrote: > > >Don't worry about leaving lock files around. If you really don't like it, > >put it in /tmp or /dev/shm. > > Sigh! Just seems so...messy. You can check if the file you got a lock on is the one presently on the FS. If the lockfile was unlinked, File.stat will fail; if another process created a file with the same name, the ino will differ. You can detect both situations and try again: $ cat lock.rb def lock(filename) dest = nil loop do dest.close if dest dest = File.open(filename, "ab") dest.flock(File::LOCK_EX) old_stat = dest.stat new_stat = File.stat(filename) rescue nil break if new_stat and old_stat.dev == new_stat.dev and old_stat.ino == new_stat.ino end yield ensure File.unlink(filename) rescue nil dest.close rescue nil end LOCKFILE = "lockfile" $stdout.sync = true t = Time.new fork do lock LOCKFILE do puts "A" p File.exist?(LOCKFILE) puts "Sleeping in A" sleep 10 end end sleep 1 fork do lock LOCKFILE do puts "B" p File.exist?(LOCKFILE) puts "Sleeping in B" sleep 10 end end sleep 15 puts "Attempting to get lock in C" lock LOCKFILE do puts "C" p File.exist?(LOCKFILE) end puts "Total time: #{Time.new - t}" $ ruby lock.rb A true Sleeping in A B true Sleeping in B Attempting to get lock in C C true Total time: 20.007932 -- Mauricio Fernandez - http://eigenclass.org - singular Ruby