Я никогда не использовал Thread до сих пор, но я думаю, что я должен полагаться на это в этом случае. Я хотел бы, чтобы обработать стандартный вывод и стандартный поток ошибок завитка командной строки в отдельности, потому что я хочу обменять возврата каретки в индикаторе хода (который записывается поток ошибок) в новой строкой:Как избежать последовательного создания объекта Ruby Thread в этом коде?
require "open3"
cmd="curl -b cookie.txt #{url} -L -o -"
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
pid = wait_thr.pid
# I have to process stdout and stderr at the same time but
#asyncronously, because stdout gives much more data then the stderr
#stream. I instantiate a Thread object for reading the stderr, otherwise
#"getc" would block the stdout processing loop.
c=nil
line=""
stdout.each_char do |b|
STDOUT.print b
if c==nil then
c=""
thr = Thread.new {
c=stderr.getc
if c=="\r" || c=="\n" then
STDERR.puts line
line=""
else
line<<c
end
c=nil
}
end
#if stderr still holds some output then I process it:
line=""
stderr.each_char do |c|
if c=="\r" || c=="\n" then
STDERR.puts line
line=""
else
line<<c
end
end
exit_status = wait_thr.value.exitstatus
STDERR.puts exit_status
end #popen3
Мой вопрос заключается в том могу ли я избежать создания нового экземпляра Thread во время цикла цикла при обработке stdout (stdout.each_char)? Я думаю, что это требует много времени, я хотел бы создать экземпляр один раз, а затем использовать его методы, такие как остановка и запуск и т. Д.
Почему обе эти логические части читают 'stderr.getc' (вторая использует' each_char')? –
Поскольку я испытал, что поток stderr все еще содержит данные, когда stdout уже пуст. – Konstantin
Вам будет гораздо лучше использовать select для управления чтением из нескольких объектов ввода-вывода. –