Thread.exclusive实际上做了什么?

maa*_*sha 2 ruby multithreading

来自API的信息非常稀少 - 也考虑到Thread.critical似乎没有记录.

在Thread.critical中包装一个块,在从临界区退出时恢复原始值,并返回该块的值.

tes*_*ssi 6

tl; dr:它使给定的块执行,因此没有其他ruby线程可以中断它.

文档具有Thread.exclusive误导性,因为它提到了Thread.critical= 在ruby 1.9版中删除的内容.但是,我们可以通过查看ruby源代码来推断它的功能.

在MRI Thread.exclusive中定义prelude.rb.因为它是一个非常短的文件,我会在这里引用它的内容:

class Thread
  MUTEX_FOR_THREAD_EXCLUSIVE = Mutex.new # :nodoc:

  def self.exclusive
    MUTEX_FOR_THREAD_EXCLUSIVE.synchronize{
      yield
    }
  end
end

这里的Thread类由一个静态常量扩展MUTEX_FOR_THREAD_EXCLUSIVE,它保存一个Mutex.当exclusive被调用时,我们要求互斥体synchronize块的执行.

Mutex的文档中所述,synchronize获取锁,运行块,并在块完成时释放锁.

因为互斥锁是线程全局状态,所以只有一个Thread可以同时保存它.

这样可行:

# no other Thread can do something between this puts statements
Thread.exclusive do
  puts 1
  puts 2
end

但这不会:

Thread.exclusive do
  puts 1
  Thread.exclusive do
    puts 2
  end  
  puts 3
end

因为这个错误:ThreadError: deadlock; recursive locking.