Я пытаюсь настроить сценарий 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
и снова зацикливается, прокручивая верхнюю часть окна консоли.
Две вещи, которые я пробовал:
Я открывал входной fifo как с "r", так и с "r+" - у меня та же проблема в любом случае;
Я попытался определить, отправляет ли мой процесс записи 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 вернутся немедленно — я ожидайте, что они заблокируют.