Как исключения ruby ​​вызывают разблокировку мутаций?

Недавно я работал с потоками Ruby и обнаружил несколько неожиданное поведение. В критической секции вызов raise приводит к освобождению мьютекса. Я мог ожидать этого от метода synchronize с его блоком, но это также происходит, когда lock и unlock вызываются отдельно.

Например, приведенный ниже код выводит:

$ ruby testmutex.rb 
x sync
y sync

... где я ожидаю, что y будет заблокировано до тепловой смерти Вселенной.

m = Mutex.new


x = Thread.new() do
  begin
    m.lock
      puts "x sync"
      sleep 5
      raise "x err"
      sleep 5
    m.unlock 
  rescue 
  end
end


y = Thread.new() do
  sleep 0.5
  m.lock
    puts "y sync"
  m.unlock 
end


x.join
y.join

Почему потоку y разрешено запускаться, даже если m.unlock в потоке x никогда не выполняется?

5
задан David Nehme 30 September 2011 в 18:13
поделиться