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