【问题标题】:Ruby, waiting for callbacksRuby,等待回调
【发布时间】:2015-02-04 21:04:53
【问题描述】:

我正在使用ruby-mpd 库编写一个mpd 客户端。它有回调驱动的事件监听器,但我不知道如何等待回调被执行。o

require 'ruby-mpd'

puts "started new thread"
mpd = MPD.new('localhost', '6600', callbacks: true)

# MPD#connect and MPD#disconnect fire the `:connection` event.
mpd.on(:connection) do |connection|
  if connection
    puts 'connected...'
  else
    puts 'disconnected'
  end
end

mpd.connect

如果我在 IRB 中逐行运行,connected 将在 mpd.connect 之后打印,但如果我将其作为脚本运行,它会在调用 connect 后立即退出(在调用回调之前?) 在文件末尾添加sleep 调用也无济于事。

我怎样才能让这个脚本永远不会退出并等待来自用户的终止信号?

好的,我查看了 ruby​​-mpd 如何实现回调。它产生一个线程,该线程循环一个更新状态对象的块。如果对象发生变化,它会发出一个事件。

我认为我最初的示例错过了 connection 属性的更改,因此甚至从未被解雇。

require 'ruby-mpd'

mpd = MPD.new('localhost', '6600', callbacks: true)

mpd.on(:connection) do
  puts 'connected...'
end

mpd.on(:state) do |state|
  puts state
end

mpd.on(:time) do |elapsed_time, total|
  puts "#{elapsed_time}/#{total}"
end

mpd.connect

while true; end

【问题讨论】:

  • 你试过while true; end 吗?
  • while true; end 确实有效,我希望它能阻止并阻止其他线程或 procs 运行。
  • 这会浪费 CPU 时间,但您可以在其中添加一个小的 sleep 语句来帮助解决这个问题。它不会阻塞其他线程,这是拥有操作系统的要点之一。
  • MPD 对象将回调线程存储在一个实例变量中,所以我只是抓住它并调用了导致主线程休眠的 join。

标签: ruby multithreading


【解决方案1】:

您可以将 mpd 调用包装在一个 eventmachine 块中,这将处理 while true; end 循环而不浪费 CPU 周期。您还将免费获得所有的 eventmachine I/O、延迟和计时器逻辑吗?

100% 未经测试的代码,但它会是这样的:

require 'ruby-mpd'

EventMachine.run do

  mpd = MPD.new('localhost', '6600', callbacks: true)

  mpd.on(:connection) do
    puts 'connected...'
  end

  mpd.on(:state) do |state|
    puts state
  end

  mpd.on(:time) do |elapsed_time, total|
    puts "#{elapsed_time}/#{total}"
  end

  mpd.connect

end

【讨论】:

    猜你喜欢
    • 2021-06-30
    • 2022-01-21
    • 2017-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-27
    • 2016-09-03
    相关资源
    最近更新 更多