После множества попыток проб и ошибок я в конечном итоге придумал использовать два потока, по одному для чтения из каждого потока (generator.rb
- это всего лишь сценарий, который я написал для вывода данных в стандартный поток вывода и ошибки):
require 'open3'
data = {}
Open3.popen3("ruby generator.rb") do |stdin, out, err, external|
# Create a thread to read from each stream
{ :out => out, :err => err }.each do |key, stream|
Thread.new do
until (line = stream.gets).nil? do
data[key] = line
end
end
end
# Don't exit until the external process is done
external.join
end
puts data[:out]
puts data[:err]
Он просто выводит последнюю строку, отправленную на стандартный вывод и ошибку вызывающей программой, но, очевидно, может быть расширен для выполнения дополнительной обработки (с различной логикой в каждом потоке).Метод, который я использовал до , я наконец-то придумал, что привело к некоторым сбоям из-за условий гонки;Я не знаю, уязвим ли этот код, но мне еще не приходилось сталкиваться с подобной ошибкой.