Ошибка сегментации Ruby-монитора - PullRequest
0 голосов
/ 18 апреля 2009

Я последовал примеру из 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 минут он выдает «Ошибка сегментации». Что-то связано с тупиком?

/ Jack

1 Ответ

1 голос
/ 18 апреля 2009

Поскольку ваш код стоит (с закомментированным оператором while в цикле продюсера), поток производителя просто проходит через цикл один раз и завершается. Потребитель читает одну произведенную строку из буфера, а затем остается в тупике, ожидая больше строк, которые никогда не поступят.

В планировщике потоков Ruby есть встроенное обнаружение взаимоблокировок, поэтому он завершит работу программы, когда обнаружит, что цикл потребителя заблокирован.

Чтобы увидеть тупик, превратите производителя в глобальную переменную $producer и заключите оператор цикла в $consumer = Thread.start do ... end. Загрузка кода в irb и оценка $ provider должны привести к => # (и $ consumer в спящем потоке)

Уберите комментарии, относящиеся к циклу while производителя, и вы получите работающий (бесконечный) цикл, который выдает текущее время с интервалом в 2 секунды.

...