Никто не решает, какой процесс запускается первым.Дочерний процесс может запускаться первым - или родительский процесс может запускаться первым - ОС может планировать их в любом случае.
Это означает, что родительский процесс может завершиться до завершения дочернего процесса.Когда родительский процесс завершается, канал к нему закрывается, и когда дочерний процесс пишет в него, он получает исключение.Вот что происходит в вашем коде.
Почему это не происходит без закомментированной строки?Когда вы вызываете gets
в родительском процессе, он ждет, пока дочерний процесс не записывает строку в канал.Это означает, что родитель не завершит работу, пока ребенок не напишет строку в канал, и это пренебрегает проблемой.Однако при печати двух строк вероятность того, что родительский процесс завершится до того, как дочерний процесс выполнит второе puts "M'kay"
увеличение.
Попробуйте следующий код:
pipe = IO.popen("-","w+")
puts "This line will not break functionality"
puts "This line will not break functionality"
puts "This line will not break functionality"
if pipe != nil then
pipe.puts "PID: #{Process.pid}"
while line = pipe.gets
$stderr.puts "Parent from child: #{line.chomp}"
end
else
$stderr.puts "Child PID: #{Process.pid} and Parent #{gets.chomp}"
puts "M'kay"
end
Он ждет, пока дочерний объект не закроет канал (тогда pipe.gets
вернет nil
), что произойдет, затем он завершится, и он гарантирует, что больше не будет пытаться писать туда.