如何请求非阻塞锁?
当单独尝试锁定文件时,为什么Ruby的File#flock无法像预期那样工作? 在块中锁定文件不是解决此问题的正确方法,因为要展示的是对持久性锁定的行为。在块内使用File#flock会在块退出时释放锁,因此不能正确地展示问题。
在请求非阻塞锁时,File#flock会以各种方式失败,以下是一些示例:
使用File#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', 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 "根据锁定常量(表格下方值的逻辑或)锁定或解锁文件"。但是,逻辑或会在不同平台上引发 Errno::EINVAL
或 Errno::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
更喜欢本地文件#flock解决方案
虽然可以使用Timeout模块当无法获得独占锁时引发Timeout::Error
,但是似乎File#flock应该能够以本地方式解决此问题。那么,如何请求独占锁而不会阻塞呢?