Thread and Mutex in Ruby 1.8.7


#1

Hello, in ruby 1.8.7

I want to do something like this:

require ‘thread’
class Bar
def initialize(f)
@f=f
end

def m_a #This method isn’t call only by FOO::m_b
@f.m_a
end
end

class Foo
 def initialize
  @mutex=Mutex.new
 end

 def m_a
  @mutex.synchronize do
   puts “A”
  end
 end

 def m_b
  @mutex.synchronize do
   puts “B”
b=Bar.new(self)
b.m_a
  end
 end
end

f=Foo.new
f.m_b

I must have

A
B

but I have
B
test.rb:8:in synchronize': stopping only thread (ThreadError)     note: use sleep to stop forever     from test.rb:8:inm_a’
    from test.rb:16:in m_b'     from test.rb:14:insynchronize’
    from test.rb:14:in `m_b’
    from test.rb:22

because I can’t do

mutex=Mutex.new
mutex.synchronize do
mutex.synchronize do
puts “A”
puts “B”
end
end

Nevertheless my thread have a lock on the mutex. How to reuse it ?

Thanks


#2

On 05.05.2009, at 14:35, Guillaume Gdo wrote:

mutex=Mutex.new
mutex.synchronize do
mutex.synchronize do
puts “A”
puts “B”
end
end

Mutex is not reentrant.

irb> m=Mutex.new
irb> m.synchronize do
irb> puts “foo”
irb> m.synchronize do
irb> puts “bar”
irb> end
irb> end
foo
ThreadError: thread 0x341ac tried to join itself
from (irb):4:in synchronize' from (irb):4 from (irb):2:insynchronize’
from (irb):2

Nevertheless my thread have a lock on the mutex. How to reuse it ?

Use Monitor instead of Mutex.

irb> m=Monitor.new
irb> m.synchronize do
irb> puts “foo”
irb> m.synchronize do
irb> puts “reentrant”
irb> end
irb> end
foo
reentrant

hth. Sandor
Szücs


#3

On 09.05.2009 14:32, Sandor Szücs wrote:

Mutex is not reentrant.
from (irb):4:in `synchronize’
irb> m=Monitor.new
irb> m.synchronize do
irb> puts “foo”
irb> m.synchronize do
irb> puts “reentrant”
irb> end
irb> end
foo
reentrant

And then there is also MonitorMixin which adds monitor functionality to
every class or instance.

Kind regards

robert