Hello again,
I repost about this thread because it seems to be a bug in ruby and
nobody replied.
I made a simplier script to test it. I think this use of flock is valid
and should not block all threads (other threads not concerned by the
lock are also blocked).
I tested it with fork instead of threads and it seems to work.
File.flock might not be thread safe?
The script creates 2 threads that infinitly lock and read a file. Each
thread displays what it does before the function call and the result is:
mike@photon:~$ ruby -vw tmp/flock.rb
ruby 1.6.4 (2001-06-04) [i686-linux]
0: Open
0: Lock
0: Read
1: Open
1: Lock
tmp/flock.rb:9:in `initialize': Interrupt
from tmp/flock.rb:9:in `new'
[...]
Thread #0's Read (f.gets) never returns, so Thread #1 cannot lock the
file.
Here is the script:
Filename = "/tmp/flock-test"
f = open(Filename, "w")
f.puts "foo"
f.close
2.times { |i|
Thread.new {
begin
loop do
puts "#{i}: Open"
f = open(Filename)
puts "#{i}: Lock"
f.flock(File::LOCK_EX)
puts "#{i}: Read"
puts "#{i}: " + f.gets
#puts "#{i}: Unlock"
#f.flock(File::LOCK_UN)
puts "#{i}: Close"
f.close
end
rescue Exception => e
p e
end
}
}
Mike.
midulo.
On Fri, 22 Jun 2001 01:28:52 +0900
Michael Witrant <mike / lepton.fr> wrote:
> Hello,
>
> I try to use File.flock to lock a file in a cgi script, but I can't
get
> it to work in my test script.
> It creates a file and write "foo". A thread that will write "bar" in
0.1
> secondes is started, and an infinite loop reads the file and print the
> result.
> The script displays some "foo" and waits, probably for the file to be
> unlocked. No "bar". I expected some "foo", then many "bar".
>
> Here is the script:
>
> filename = "/tmp/flock-test"
>
> f = open(filename, "w")
> f.puts "foo"
> f.close
>
> Thread.new {
> sleep .1
> f = open(filename, "w")
> f.flock(File::LOCK_EX)
> f.puts "bar"
> f.flock(File::LOCK_UN)
> f.close
> }
>
> loop do
> f = open(filename)
> f.flock(File::LOCK_EX)
> puts f.gets
> f.flock(File::LOCK_UN)
> f.close
> end
>
> With the help of some puts, it seems to be blocking on f.gets in the
> main thread and f.flock in the writing thread.
> If I add "sleep .0001" in the main loop, it works.
>
> Where am I wrong?
>
> I tried to search "flock" on ruby-talk.com, but I got an Internal
Server
> Error.
>
>
> Mike.
> midulo.
>