Ruby 守护程序中的错误文件描述符

Posted

技术标签:

【中文标题】Ruby 守护程序中的错误文件描述符【英文标题】:Bad File Descriptor in Ruby Daemons 【发布时间】:2012-06-02 21:36:07 【问题描述】:

在 Mac OS X Lion 上使用 Ruby v1.8.7 和 Daemons v1.1.8,我正在尝试编写一个消费者进程并让它作为守护进程运行:

# config[:name] => 'idx_my_delete_consumer' # config[:daemon] => :multiple => false, # :backtrace => true, # :dir_mode => :normal, # :log_dir => '/Users/pprakash/consumer.log', # :monitor => true, # :dir => '/Users/pprakash/pids' Daemons.run_proc(config[:name], config[:daemon]) 做 消费者 = MyConsumer.new(config) 消费者订阅 结尾

但是,它并没有启动,而是抛出了一个很长的回溯,如下所示:

E, [2012-05-28T19:34:16.199770 #29357] 错误 -- : 错误的文件描述符 (Errno::EBADF) /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons/daemonize.rb:134:in `for_fd' /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons/daemonize.rb:134:in `close_io' /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons/daemonize.rb:134:in `initialize' /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons/daemonize.rb:134:in `new' /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons/daemonize.rb:134:in `close_io' /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons/daemonize.rb:75:in `call_as_daemon' /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons/application.rb:258:in `start_proc' /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons/application.rb:295:in `start' /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons/monitor.rb:51:in `watch' /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons/monitor.rb:51:in `fork' /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons/monitor.rb:51:in `watch' /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons/monitor.rb:45:in `each' /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons/monitor.rb:45:in `watch' /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons/monitor.rb:44:in `loop' /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons/monitor.rb:44:in `watch' /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons/monitor.rb:84:in `start_with_pidfile' /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons/monitor.rb:64:in `fork' /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons/monitor.rb:64:in `start_with_pidfile' /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons/monitor.rb:111:in `start' /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons/application_group.rb:149:in `create_monitor' /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons/application.rb:284:in `start' /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons/controller.rb:70:in `run' /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons.rb:197:in `run_proc' /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons/cmdline.rb:109:in `call' /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons/cmdline.rb:109:in `catch_exceptions' /opt/local/lib/ruby/gems/1.8/gems/daemons-1.1.8/lib/daemons.rb:196:in `run_proc' 用户/delete_consumer.rb:40

我不确定是什么导致了这个问题?目录名、日志文件名都有效。我可以使用这些配置创建 MyConsumer 的实例,并能够从独立程序/控制台正确执行其#subscribe。

【问题讨论】:

因此,在获得了 Ruby 守护进程的一些经验之后,我开始意识到任何此类错误都意味着底层块(被妖魔化)有错误。修复底层块中的所有错误也修复了这个错误。 我遇到了同样的问题。感谢您分享您的发现! 为了帮助别人,回答你自己的问题,让它有一个正式的答案。 为了能够获得更好的支持并拥有更好的环境,我强烈建议您将本地 Ruby 升级到 1.9.3,而不是与 Mac OS X 一起分发的更旧的 1.8.7。跨度> 【参考方案1】:

根据我使用 Ruby 守护程序的经验,我发现此类错误表明底层块(已守护程序)包含错误。修复这些错误也会修复此错误。

【讨论】:

在我的例子中,问题是我在守护循环中调用的库默认写入标准输出,除了我明确告诉它做的事情。但是守护进程没有标准输出!因此,它引发了错误的文件描述符异常。【参考方案2】:

您的示例中确实存在可能导致错误的拼写错误。检查 MyConsumer 的拼写,您将 s 和 n 调换...

consumer = MyCosnumer.new(config) 

【讨论】:

感谢您指出错字。它可能在我发布问题时已经到达这里。编辑并从问题中删除它

以上是关于Ruby 守护程序中的错误文件描述符的主要内容,如果未能解决你的问题,请参考以下文章

如何通过命名管道传输文件描述符

recvfrom 函数中的错误文件描述符

Linux中的文件描述符与打开文件之间的关系

为啥我会收到错误的文件描述符错误?

c read() 导致错误的文件描述符错误

提升 asio 绑定:错误的文件描述符