我怎样才能使用文件#羊群的排他锁无阻塞的要求吗?(How can I make a non-bloc

2019-08-17 10:12发布

我应该如何申请一个非阻塞锁?

为什么不Ruby的文件#羊群如预期工作时单独尝试以锁定文件? 锁定在一个块中的文件不是针对此问题的正确解决方案,因为该点是展示持久锁锁定的行为。 使用文件#羊群块内释放锁当块退出,所以它不能正确说明问题。

文件#羊群多种方式发生故障,请求非阻塞锁时尤其如此。 下面是一些例子。

与文件#羊群失败的例子

  • 使用多排它锁时,因为#flock不提供一种方式来超时锁定请求无限期等待。

     # First lock succeeds. f1 = File.open('foo', File::RDWR|File::CREAT, 0644) f1.flock(File::LOCK_EX) # => 0 # This never returns. f2 = File.open('foo', File::RDWR|File::CREAT, 0644) f2.flock(File::LOCK_EX) 
  • 要求一个非阻塞的锁,而该文件是一个无效的参数异常独占锁定的结果。

     f1 = File.open('foo', File::RDWR|File::CREAT, 0644) f1.flock(File::LOCK_EX) # => 0 f2 = File.open('foo', File::RDWR|File::CREAT, 0644) f2.flock(File::LOCK_NB) # => Errno::EINVAL: Invalid argument - foo 
  • 文档说#flock“锁定或解锁根据locking_constant一个文件(一个逻辑或在下面的表中的值的)。” 然而,逻辑或引发Errno::EINVALErrno::EBADF取决于平台。

     f1 = File.open('foo', File::RDWR|File::CREAT, 0644) f1.flock(File::LOCK_EX) # => 0 f2 = File.open('foo', File::RDWR|File::CREAT, 0644) f2.flock(File::LOCK_NB || File::LOCK_EX) # => Errno::EINVAL: Invalid argument - foo 

本地文件#羊群中优选的

虽然人们可能使用超时模块 ,以提高Timeout::Error当无法获取排它锁,好像文件#羊群应该能够解决原生这个问题。 那么,如何在一个实际上应该请求独占锁不阻塞?

Answer 1:

使用超时模块与互斥锁

您可以使用超时模块设置一个持续时间#flock获得排它锁。 下面的例子将提高Timeout::Error: execution expired ,然后可以以任何方式似乎是适当的应用程序被救出。 返回当定时器到期时允许#flock表达为真理进行测试。

require 'timeout'

f1 = File.open('foo', File::RDWR|File::CREAT, 0644)
f1.flock(File::LOCK_EX)
# => 0

f2 = File.open('foo', File::RDWR|File::CREAT, 0644)
Timeout::timeout(0.001) { f2.flock(File::LOCK_EX) } rescue nil
# => nil

用位或对于非阻塞的锁定尝试

对于文档文件#羊群说:

锁定或解锁根据locking_constant一个文件(在下面的表中的逻辑或的值的)。 如果指定文件:: LOCK_NB和操作本来会阻止返回false。

然而,该方法实际上需要一个按位或运算符,而不是作为一个逻辑或关键词在parse.y定义由tOROP解析器令牌。 因此,正确的说法,让#flock返回false时的排他锁失败实际上是File::LOCK_NB|File::LOCK_EX 。 例如:

f1 = File.open('foo', File::RDWR|File::CREAT, 0644)
f1.flock(File::LOCK_EX|File::LOCK_NB)
# => 0

f2 = File.open('foo', File::RDWR|File::CREAT, 0644)
f2.flock(File::LOCK_NB|File::LOCK_EX)
# => false

f1.close; f2.close
# => nil

这将始终如一地产生时可用的排他锁; 否则,它会立即返回一个值falsy不提高或抢救异常的开销。 这显然是该模块的目的是使用方式,但文档可以使用一些澄清和额外的例子,使其更容易理解。



文章来源: How can I make a non-blocking request for an exclusive lock using File#flock?