0

我按照http://www.ruby-doc.org/stdlib/libdoc/monitor/rdoc/index.html中的示例对代码进行了一些修改:

require 'monitor.rb'

buf = []
buf.extend(MonitorMixin)
empty_cond = buf.new_cond

producer = Thread.start do
# producer
line = "produce at #{Time.now}"
#while line
  buf.synchronize do
    puts "==> #{line}"
    buf.push(line)
    empty_cond.signal
  end
  sleep(2)
  #line = "produce at #{Time.now}"
#end
end

loop do
   buf.synchronize do
      empty_cond.wait_while { buf.empty? }
      item = buf.shift
      puts "got #{item.inspect}"
   end
end

我让程序运行。大约 5 分钟后,它会抛出“分段错误”。与死锁有关的东西?

/杰克

4

1 回答 1

1

正如您的代码所代表的那样(在生产者循环中带有注释掉的 while 语句),生产者线程只需运行一次循环并退出。消费者从 buf 读取一条生产线,然后陷入僵局,等待更多永远不会到达的线。

Ruby 的线程调度程序具有内置的死锁检测功能,因此它会在看到“消费者”循环已死锁时终止程序。

要亲自查看死锁,请将生产者转换为全局变量$producer并将循环语句用$consumer = Thread.start do ... end. 将代码加载到 irb 并评估 $producer 应该会导致 => #< Thread:0x000000010afb58 dead > (并且 $consumer 在休眠线程中)

取出与生产者的 while 循环相关的注释,您将拥有一个工作(无限)循环,该循环以 2 秒的间隔生成当前时间。

于 2009-04-18T06:40:11.067 回答