$stdin
содержит поток для стандартного ввода.Его можно использовать для чтения ввода с консоли.
$stdin
является экземпляром класса IO
.Этот класс определяет метод read
, который читает байты из потока ввода-вывода.Вы можете указать количество байтов для чтения из потока с помощью аргумента length
до read
.Если length
опущен или равен nil
, он читает до EOF
.
Я почти уверен, что IO.read
блокирует.Учитывая его блокирующий характер, я рассматриваю следующий код:
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
pid = wait_thr.pid
begin
Timeout.timeout(TIMEOUT) do
output = [stdout.read, stderr.read]
Process.wait(pid)
end
rescue Errno::ECHILD
rescue Timeout::Error
Process.kill('HUP', pid)
fail
end
end
Он использует Open3.popen3
, который открывает потоки stdin
, stdout
и stderr
и запускает внешний исполняемый файл.wait_thr.pid
дает pid
запущенного процесса.
Теперь обратите внимание на использование stdout.read and stderr.read
.Поскольку stdout
и stderr
являются экземплярами IO
, они используют IO#read
.Этот метод блокирует.
Следующая строка исполнения имеет Process.wait(pid)
.Process.wait
ожидает завершения pid
(процесс), возвращает его идентификатор процесса и устанавливает $?
для объекта Process::Status
, содержащего информацию об этом процессе.
Но если stdout.read
и stderr.read
блокируется, как Process.wait
может ждать завершения процесса?Другими словами, если по какой-то причине stdout.read
зависает, как Process.wait
может ожидать завершения процесса?