Ruby自从版本2.0以来就对线程局部变量提供了本机支持。但是,active_ support /core_ext/线程. of实现了纯Ruby中的此特性,以支持ruby早期版本中的线程局部变量。因此,我想知道为什么我们应该在_locals方法中使用互斥:
发布于 2014-04-06 15:39:54
_locals做了两件事:
def _locals
# 1. Returns the local variable hash when defined
if defined?(@_locals)
@_locals
# 2. Lazily instantiates a locals hash
else
LOCK.synchronize { @_locals ||= {} }
end
end需要这个同步步骤来确保@_locals在第一次访问期间从未被清除。
考虑以下情况:
thread = Thread.new
# Say I run this statement...
thread.thread_variable_set('a', 1)
# In parallel with this statement...
thread.thread_variable_get(:a)这两个方法都调用_locals,如果它们同时执行,它们都可能在延迟分配步骤中结束:
@_locals ||= {}
# Expands to...
unless @_locals
@_locals = {} # <-- We could end up here with both threads at the same time,
end # which jeopardizes any value that might have been set.因此,假设我们没有互斥对象,而setter完成了执行,而getter则进入了延迟分配步骤。由于线程冲突,我们实际上已经失去了所设置的所有局部变量。在互斥体上调用同步保证块在没有任何此类冲突的情况下执行到完成。
请注意,支持访问线程局部变量的Ruby版本不会加载核心扩展。请看最后一行:
unless Thread.instance_methods.include?(:thread_variable_set)https://stackoverflow.com/questions/22891503
复制相似问题