Как заблокировать чтение именованного канала в Ruby?

Я пытаюсь настроить сценарий Ruby, который читает из именованного канала в цикле, блокируя до тех пор, пока в канале не появятся входные данные.

У меня есть процесс, который периодически помещает отладочные события в именованный канал:

# Open the logging pipe
log = File.open("log_pipe", "w+") #'log_pipe' created in shell using mkfifo
...
# An interesting event happens
log.puts "Interesting event #4291 occurred"
log.flush
...

Затем мне нужен отдельный процесс, который будет читать из этого канала и выводить события на консоль по мере их возникновения. Я пробовал использовать такой код:

input = File.open("log_pipe", "r+") 
while true
  puts input.gets  #I expect this to block and wait for input
end
# Kill loop with ctrl+c when done

Я хочу, чтобы input.getsблокировался, терпеливо ожидая, пока новый ввод не поступит в FIFO; но вместо этого он немедленно читает nilи снова зацикливается, прокручивая верхнюю часть окна консоли.

Две вещи, которые я пробовал:

  1. Я открывал входной fifo как с "r", так и с "r+" - у меня та же проблема в любом случае;

  2. Я попытался определить, отправляет ли мой процесс записи EOF (что, как я слышал, приведет к закрытию буфера чтения) — насколько я знаю, это не так.

НЕКОТОРЫЙ КОНТЕКСТ:

Если это поможет, вот общий вид того, что я пытаюсь сделать:

Я работаю над игрой, которая работает в RGSS, игровом движке на основе Ruby. Поскольку у него нет хорошей встроенной отладки, я хочу настроить журнал в реальном времени во время работы игры — когда в игре происходят события, я хочу, чтобы сообщения отображались в окне консоли сбоку. Я могу отправлять события в коде игры Ruby в именованный канал, используя код, аналогичный приведенному выше коду записи; Сейчас я пытаюсь настроить отдельный процесс, который будет ждать появления событий в канале и показывать их на консоли по мере их поступления. Я даже не уверен, что для этого мне нужен Ruby, но это было первое решение, которое пришло мне в голову.

Обратите внимание, что я использую mkfifoиз cygwin, который я все равно установил; Интересно, может ли это быть источником моей беды?

Если это кому-нибудь поможет, вот что я вижу в irb с моим процессом 'reader':

irb(main):001:0> input = File.open("mypipe", "r")
=> #<File:mypipe>
irb(main):002:0> x = input.gets
=> nil
irb(main):003:0> x = input.gets
=> nil

Я не ожидаю, что input.getsпо адресам 002 и 003 вернутся немедленно — я ожидайте, что они заблокируют.

5
задан WaveformDelta 22 March 2012 в 04:40
поделиться