This page contains automated test results for code from O'Reilly's Ruby Cookbook. If this code looks interesting or useful, you might want to buy the whole book.
| Locking a File | ||
|---|---|---|
| Code | Expected | Actual |
def flock(file, mode)
success = file.flock(mode)
if success
begin
yield file
ensure
file.flock(File::LOCK_UN)
end
end
return success
end
open('output', 'w') do |f|
flock(f, File::LOCK_EX) do |f|
f << "Kiss me, I've got a write lock on a file!"
end
end
def open_lock(filename, openmode="r", lockmode=nil)
if openmode == 'r' || openmode == 'rb'
lockmode ||= File::LOCK_SH
else
lockmode ||= File::LOCK_EX
end
value = nil
open(filename, openmode) do |f|
flock(f, lockmode) do
begin
value = yield f
ensure
f.flock(File::LOCK_UN) # Comment this line out on Windows.
end
end
return value
end
end
t1 = Thread.new do
puts 'Thread 1 is requesting a lock.'
open_lock('output', 'w') do |f|
puts 'Thread 1 has acquired a lock.'
f << "At last we're alone!"
sleep(5)
end
puts 'Thread 1 has released its lock.'
end
t2 = Thread.new do
puts 'Thread 2 is requesting a lock.'
open_lock('output', 'r') do |f|
puts 'Thread 2 has acquired a lock.'
puts "File contents: #{f.read}"
end
puts 'Thread 2 has released its lock.'
end
t1.join
t2.join |
Thread 1 is requesting a lock. Thread 1 has acquired a lock. Thread 2 is requesting a lock. Thread 1 has released its lock. Thread 2 has acquired a lock. File contents: At last we're alone! Thread 2 has released its lock. |
Thread 1 is requesting a lock. Thread 1 has acquired a lock. Thread 2 is requesting a lock. Thread 1 has released its lock. Thread 2 has acquired a lock. File contents: At last we're alone! Thread 2 has released its lock. |
def try_lock
puts "I couldn't get a lock." unless
open_lock('contested', 'w', File::LOCK_EX | File::LOCK_NB) do
puts "I've got a lock!"
true
end
end
try_lock |
I've got a lock! |
I've got a lock! |
open('contested', 'w').flock(File::LOCK_EX) # Get a lock, hold it forever.
try_lock |
I couldn't get a lock. |
I couldn't get a lock. |