ruby – 如何使用File#flock对独占锁进行非阻塞请求?
我应该如何请求非阻塞锁?
为什么Ruby 7 File#flock在单独尝试锁定文件时工作正常?将文件锁定在块中不是解决此问题的正确解决方案,因为重点是显示锁定持久锁的行为.在块中使用File#flock释放锁,当该块退出时,它不会正确显示问题. File#flock以各种方式失败,特别是在请求非阻塞锁时.一些例子如下. 失败的文件#flock的例子 >使用多个独占锁时,无限等待,因为#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',0644) f2.flock(File::LOCK_EX) >当文件被专门锁定时,请求非阻塞锁导致无效的参数异常. f1 = File.open('foo',0644) f1.flock(File::LOCK_EX) # => 0 f2 = File.open('foo',0644) f2.flock(File::LOCK_NB) # => Errno::EINVAL: Invalid argument - foo >文档说#flock“根据locked_constant锁定或解锁文件(逻辑或下表中的值)”.但是,逻辑OR会根据平台引发Errno :: EINVAL或Errno :: EBADF. f1 = File.open('foo',0644) f2.flock(File::LOCK_NB || File::LOCK_EX) # => Errno::EINVAL: Invalid argument - foo 本机文件#flock解决方案首选 虽然可能使用Timeout module来提高超时::错误时无法获得排他锁,似乎File#flock应该能够本来解决这个问题.那么,一个实际上应该如何请求一个排他锁呢? 解决方法
使用具有独占锁的超时模块
您可以使用Timeout module设置#flock的持续时间来获取排他锁.以下示例将引发超时::错误:执行过期,然后可以以适用于应用程序的任何方式进行抢救.当定时器到期时返回零,允许#flock表达式被测试为真值. require 'timeout' f1 = File.open('foo',0644) Timeout::timeout(0.001) { f2.flock(File::LOCK_EX) } rescue nil # => nil 使用按位或进行非阻塞锁定尝试 File#flock的文档说:
然而,该方法实际上期望一个Bitwise OR运算符,而不是逻辑OR关键字为defined in parse.y由tOROP解析器令牌.结果,允许#flock在排除锁定失败时返回false的正确参数实际上是File :: LOCK_NB | File :: LOCK_EX.例如: f1 = File.open('foo',0644) f1.flock(File::LOCK_EX|File::LOCK_NB) # => 0 f2 = File.open('foo',0644) f2.flock(File::LOCK_NB|File::LOCK_EX) # => false f1.close; f2.close # => nil 这可以一直生成排他锁;否则,它立即返回一个伪造值,而不会引发或拯救异常.这显然是模块的使用方式,但文档可以使用一些澄清和其他示例来使其更容易理解. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |