Ruby在semaphore.synchronize块中返回

时间:2018-08-18 00:15:56

标签: ruby mutex

我想知道如果我执行以下操作,信号量是否会释放锁:

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

运行此函数的线程是否会继续持有此锁直到其终止?还是return语句会释放锁?

3 个答案:

答案 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方法之前使用一个变量,在块内获取分配给该变量的返回值,然后在块执行完成后使用分配的值访问该变量。