Ruby Return semaphore.synchronize 区块内

Ruby Return Within semaphore.synchronize Block

我想知道如果我这样做,信号量是否会释放锁:

def test
  semaphore.syncronize do
    if (access_shared_resource)
      return "Condition A"
    else
      return "Condition B"
    end
  end
end

线程 运行 这个函数会继续持有这个锁直到它终止吗?还是return语句会释放锁?

根据文档,它会在完成块(传递给 syncronize 的块)后释放: https://ruby-doc.org/core-2.5.0/Mutex.html#method-i-synchronize

为了在这个答案被否决时提供更多证据,这里是同步的实现。我不是 C 专家,但从我在这里看到的情况来看,解锁是在 ensure 中实现的,所以这个互斥量将在块终止时解锁,无论它是返回还是通过跳转离开: https://github.com/ruby/ruby/blob/2cf3bd5bb2a7c4724e528577d37a883fe80a1122/thread_sync.c#L512

快速建模也支持这一点: https://repl.it/repls/FailingWearableCodewarrior

来自块的

Returns 很棘手,并且在 ruby 的不同实现之间可能会在倒回堆栈帧的方式上有所不同。尽可能避免从块返回(提示:它总是可能的。)

与其纠结于 returns,不如使用 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

您可以在同步方法之前有一个变量,在块中获取分配给该变量的 return 值,然后在块执行完成后访问具有分配值的变量。