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

/Jack

ответ

1

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

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

Чтобы увидеть тупик для себя, превратите производителя в глобальную переменную $producer и заверните loop-statement $consumer = Thread.start do ... end. Загрузка кода в irb и оценка $ производителя должны привести к => # < Тема: 0x000000010afb58 dead> (и $ consumer во спальной нити)

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

Смежные вопросы