异常究竟是如何解锁互斥体的?

How exactly exception unlocks mutex?

这个简单的测试主要结果为
(1) rescue break, m.locked?: false
但有时我能看到
(1) rescue break, m.locked?: true

m = Mutex.new

6.times do

    Thread.new do
        begin
            m.synchronize do
                puts 't1 action'
                3.times do
                    puts '.'
                    sleep 0.5
                end
                raise 'Break'
            end
        rescue 
            puts "(1) rescue break, m.locked?: #{m.locked?}"
            m.synchronize do
                sleep 0.1
            end
            puts '(2) after m {sleep}'
            sleep 0.1
            puts 'rescue break 2'
        end
    end

    sleep 0.1
    t2 = Thread.new do
        puts 't2 waiting for mutex'
        m.synchronize do
            puts '(3) t2 action'
        end
    end

    t2.join
    sleep 0.2
    puts;puts;
end

我预计救援块内的互斥量将始终解锁。

环境: Ruby v2.6.3.62 (2019-04-16) [x64-mingw32]

没有人承诺处理器会停止世界,等待你的行动:)也就是说,在

之间
raise 'Break'

puts "(1) rescue break, m.locked?: #{m.locked?}"

有另一个线程可能获得执行时间并依次锁定互斥量


另请注意,

    raise 'Break'
  end
rescue 
  puts "(1) rescue break, m.locked?: #{m.locked?}"

实际上与

相同
  end
  puts "(1) rescue break, m.locked?: #{m.locked?}"

在后一个片段中,应该清楚 m 可能被另一个线程锁定,也可能没有;我们刚刚发布,所以没有承诺。