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