如何使用 File#flock 发出非阻塞独占锁请求?

2024-04-26

如何申请非阻塞锁?

为什么 Ruby 没有文件#flock http://www.ruby-doc.org/core-2.0/File.html#method-i-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“根据locking_constant(下表中的值的逻辑或)锁定或解锁文件。”然而,逻辑或引发Errno::EINVAL or 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
    

首选原生 File#flock 解决方案

虽然人们可能会使用超时模块 http://www.ruby-doc.org/stdlib-2.0/libdoc/timeout/rdoc/Timeout.html募集Timeout::Error当无法获得独占锁时,似乎 File#flock 应该能够本地解决这个问题。那么,实际上应该如何在不阻塞的情况下请求独占锁呢?


使用带有独占锁的超时模块

您可以使用超时模块 http://www.ruby-doc.org/stdlib-2.0/libdoc/timeout/rdoc/Timeout.html设置 #flock 获取排他锁的持续时间。下面的例子将引发Timeout::Error: execution expired,然后可以通过任何适合应用程序的方式对其进行救援。返回nil当计时器到期时,可以测试 #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

使用按位或进行非阻塞锁定尝试

的文档文件#flock http://www.ruby-doc.org/core-2.0/File.html#method-i-flock says:

根据locking_constant(下表中值的逻辑或)锁定或解锁文件。如果指定了 File::LOCK_NB,则返回 false,否则操作将被阻止。

然而,该方法实际上期望按位或 http://ruby-doc.org/core-2.0/Fixnum.html#method-i-7C运算符,而不是逻辑 OR 关键字在 parse.y 中定义 https://github.com/ruby/ruby/blob/c07d78eb0e8e9d3a8f9e8c860b362964157ff43a/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

这将在可用时始终生成独占锁;否则,它会立即返回一个假值,而不会产生引发或拯救异常的开销。这显然是该模块的使用方式,但文档可以使用一些说明和附加示例来使其更易于理解。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 File#flock 发出非阻塞独占锁请求? 的相关文章

  • Sublime Text 是否支持 Ruby API(自动完成)?

    如何获取可用于某些对象或类的方法列表 如下所示 Sublime Text 有针对 Ruby 的此功能吗 像这样https github com BoundInCode Display Functions https github com B
  • 迭代比线性代码慢吗?哪一个更可取?

    最近几天我脑子里一直有一个问题 在用 ruby 编写代码时 线性代码是否比迭代更快 更好 让我举个例子 有一个用于相同功能的代码块以两种不同的方式编写 Way 1 dog cat tiger each do pet name puts I
  • ruby CSV重复行解析

    我有一些需要处理的 CSV 数据 但无法找到匹配重复项的方法 数据看起来有点像这样 line id name item 1 item 2 item 3 item 4 1 251 john foo foo foo foo 2 251 john
  • 如何查找重复字母最多的单词

    我的目标是找到给定字符串中重复字母最多的单词 例如 aabcc ddeeteefef iijjfff 会回来 ddeeteefef 因为 e 在这个单词中重复了五次 这比所有其他重复字符都多 到目前为止 这是我得到的 但它有很多问题并且不完
  • Ruby:基于控制台的菜单

    我有一个名称和 URL 数组 并希望以向上 向下滚动菜单的形式向用户呈现名称列表 基本上是什么dialog允许在外壳内 我调查过ncurses ruby rdialog and HighLine但它们似乎要么作为一个项目被放弃 要么甚至从它
  • 更快地将数据库从一个heroku应用程序传输到另一个应用程序

    有没有更快的方法将我的生产数据库传输到测试应用程序 目前我正在做一个heroku db pull然后到我的本地机器heroku db push app testapp但这变得越来越耗时 我有一些种子数据 但它并不像简单地使用我的真实数据进行
  • ruby 中的树和图数据结构[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我很难找到在 ruby 中使用的树数据结构 我可以研究一些众所周知的吗 我的要求很简单 我想创建一棵树 或者可能是一个图 并找到一些节点之
  • 动态分配背景图片scss/sass

    我想要做的是有一个表单 您可以在其中上传图片 然后当您查看该对象时 图片会在特定 div 中居中 垂直和水平向上倾斜 其大小未知等 除非有办法使用 image tag 帮助器将其垂直居中 否则我希望能够使用该图像作为背景图像 在我的 css
  • Monitor.Pulse & Wait - 意外行为

    http www codeproject com Articles 28785 Thread synchronization Wait and Pulse demystified http www codeproject com Artic
  • ruby 1.9.1 的 gem install mongrel 失败

    昨天我开始了 Rails 开发 我安装了 ruby 1 9 1 rubygems 和 Rails 跑步gem install mongrel工作得很好 表面上也安装了杂种 我有点困惑 因为 script server 默认启动 webric
  • 在 Rails 中强制内联渲染 PDF 文档

    我正在编写一个从一组 XML 文件生成 PDF 文件的服务 正在正确生成 PDF 但是 每次我单击 查看 PDF 链接时 浏览器都会要求用户下载 PDF 文件 我需要 PDF 内联显示 就像任何常规 HTML 页面一样 我虽然我写的代码是正
  • 使用 Devise 和 Rails 从 Twitter Oauth 获取电子邮件

    我已经设置了一个基本的 Rails 应用程序来使用 twitter oauth gem 和设计 并且已经能够登录用户 但是 我的问题是我现在已将我的应用程序列入白名单 并且我想在响应中收到用户的电子邮件 我已遵循 Twitter 端的所有必
  • 如何在 Mac OS X 上使用 ulimit 或每个进程更改 C 或 Ruby 程序的堆栈大小?

    似乎为 C 程序或 Ruby 程序 使用 C 堆栈 设置堆栈大小的推荐方法是使用ulimit在 Bash shell 中 但 ulimit s 8192 ulimit s 16384 bash ulimit stack size canno
  • 无法在 IE 上运行 Selenium 脚本

    我必须在 IE 10 浏览器上运行 Selenium 测试 为了运行以下脚本 我执行了以下操作 下载IEDriverServer 64位 因为我的机器是64位 here http code google com p selenium dow
  • Rails validates_与模型的错误消息相关

    我在模型中使用 validates linked 来使用其他模型的验证代码 问题是验证失败的消息是 is invalid 我想将模型验证失败的实际描述错误冒泡到顶部 我发现这个问题 验证与模型的错误消息关联 https stackoverf
  • 为什么安装 Ruby 1.9.3 时会出现 404 错误?

    我最近擦除了我的计算机 操作系统 Mac OS X 10 6 8 并重新安装了所有开发工具 我再次安装了RVM 但是 它不允许我安装 Ruby 1 9 3 到目前为止我已经尝试过 rvm install 1 9 3 rvm install
  • Ruby 解释器出现段错误后,是否可以从 corefile 中获取 Ruby 回溯?

    Note 我使用了在使用 libxml ruby gem 时遇到的段错误来说明问题 但我已经用所述 gem 解决了我的问题 这个问题真正涉及的是从 gdb 使用 corefile 查看 Ruby 回溯 即解释器在 Ruby 代码无法处理异常
  • 在 Rails 中,我可以通过委托方法订购查询吗?

    我在通过委托方法订购查询时遇到困难 我的任务是帮助将一个相当大的 Rails 3 应用程序升级到 Rails 4 我在索引操作中遇到了这个查询 我知道这些对象的命名是可怕且令人困惑的 measurements controller rb d
  • Jekyll 站点仅在推送到 GitHub 时才会失败

    我正在使用 Jekyll 开发一个新版本的静态网站 该网站通过 Github 页面部署 https devcampy com https devcampy com 存储库 https github com gianarb devcampy
  • ruby 包含问题

    class Foo def initialize a puts Hello a end end module Bar def initialize b puts b World end end class Sample lt Foo inc

随机推荐