我想知道如果我执行以下操作,信号量是否会释放锁:
def test
semaphore.syncronize do
if (access_shared_resource)
return "Condition A"
else
return "Condition B"
end
end
end
运行此函数的线程是否会继续持有此锁直到其终止?还是return
语句会释放锁?
答案 0 :(得分:3)
根据文档,一旦完成该块(传递给syncronize
的块),它将释放:
https://ruby-doc.org/core-2.5.0/Mutex.html#method-i-synchronize
为了在此答案被否决时提供更多的证据,这里是sync的实现。我不是C方面的专家,但是从我这里看到的情况来看,确保已实施了解锁,因此该互斥锁将在块终止时被解锁,无论它是返回还是通过跳转留下: https://github.com/ruby/ruby/blob/2cf3bd5bb2a7c4724e528577d37a883fe80a1122/thread_sync.c#L512
快速建模也支持此功能: https://repl.it/repls/FailingWearableCodewarrior
答案 1 :(得分:2)
从块返回数据是棘手的,在不同的ruby实现之间,它们在倒回堆栈帧的方式上可能会有所不同。尽量避免从阻止返回(提示:总是可能的。)
使用break
而不是费力的回报,它很干净,并且行为非常明确:
def test
semaphore.syncronize do
if (access_shared_resource)
break "Condition A"
else
break "Condition B"
end
end
end
或者,如果在自然块存在之前存在一些代码:
def test
case
semaphore.syncronize do
break :continue if (normal_condition)
if (access_shared_resource)
break :accessed
else
break :not_accessed
end
end
when :accessed then "Condition A"
when :not_accessed then "Condition B"
else
# normal control flow
end
end
答案 2 :(得分:0)
您可以在sync方法之前使用一个变量,在块内获取分配给该变量的返回值,然后在块执行完成后使用分配的值访问该变量。