Ruby线程不会上下文切换

时间:2011-04-27 14:39:15

标签: ruby alsa

使用MRI ruby​​ 1.9我有一些像

这样的代码
def foo()
  puts "in foo"
  loop do
    puts "in foo loop"
  end
end

def bar()
  puts "in bar"
  start_alsa_listener
end

foo_thread = Thread.new { foo }
bar_thread = Thread.new { bar }
foo_thread.join
bar_thread.join

start_alsa_listener是一个阻塞库调用,用于打开ALSA midi音序器并等待其上的输入事件。本质上,我希望我的代码能够不断地打印出“foo循环”,同时能够接收ALSA midi事件并将它们打印到控制台(start_alsa_listener在收到事件时会这样做)。

问题在于,当我运行上面的代码时,只要bar()运行它就永远不会将上下文切换回foo()。

start_alsa_listener是一个ruby C扩展,如下所示:

for(;;) {
    poll(/* args */);      /* wait for input data */
    /* print data to console */
}

也许它与Ruby中的某些东西有关我在线程上做错了,或者可能与poll有关,或者可能与ALSA处理线程的方式有关。任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:3)

你所展示的循环将阻止整个解释器(假设poll正在阻塞),就像史蒂夫所说的那样。您需要使用Ruby(MRI / YARV)C API中的rb_thread_blocking_region调用poll()。

答案 1 :(得分:2)

没有文本,这两个文本并行运行。 GIRL不会让两个线程同时使用C扩展运行,因为它无法知道它的线程安全。