Задать вопрос
pluffie
@pluffie
Стыдно за старые вопросы

Как языки, исполняемые на ВМ, пишут в консоль?

Захотелось мне узнать, как работает консольный вывод под капотом. Знаю, что данные просто пишутся в stdout, но тут встаёт два вопроса: 1. А как программы находят этот самый stdout? 2. Каким образом они записывают в него данные?

Хотелось бы узнать, как это работает именно в случае с языками по типу Java или C#, т.к с низкоуровневыми языками всё более-менее понятно (слышал, что в unix-подобных системах этот stdout лежит в /dev/fd/1 и записать данные в него можно используя API POSIX).
  • Вопрос задан
  • 206 просмотров
Подписаться 1 Простой Комментировать
Решения вопроса 2
saboteur_kiev
@saboteur_kiev
software engineer
stdout это просто дескриптор, который открывает консоль.

Для каждой консольной программы открывается три дескриптора с номерами 0, 1, 2 (stdin, stdout, stderr), куда они могут писать.

/dev/fd/1
Нет, fd это просто файловый дескриптор/1
правильный путь будет /proc/ID_процесса/fd/1
то есть у каждого процесса stdout свой.

Ну и еще. Неважно какой язык. Это про архитектуру операционки, а не язык.
Ответ написан
pluffie
@pluffie Автор вопроса
Стыдно за старые вопросы
Прошло уже два года а то и больше. Ответ на вопрос я, конечно, теперь уже знаю. Для таких же пытливых, каким был я, распишу всё в деталях.

На самом низком уровне (из тех, что имеет смысл рассматривать в данном вопросе) лежит ОС, на долю которой выпадает управление буквально всем и, в частности, стандартным вводом/выводом.

Начиная с этого момента, за винду в рамках данного ответа не ручаюсь и говорить буду только про POSIX.

По сути та консоль с текстом, которую видит пользователь, это обычная программа (в некоторых случаях модуль ядра), которая называется эмулятором терминала. Задача эмулятора - запустить другую программу как дочерний процесс, перенаправлять все нажатые клавиши ей в stdin и выводить на экран то, что она пишет в stdout и stderr (обычно с поддержкой управляющих последовательностей ANSI и прочей мишуры).

Любая программа не может работать с файлами, коносолью и вообще с чем-либо, минуя ОС. stdout является обычным файлом, в который можно писать ровно так же, как и в любой другой. Запись в файл, обычно, происходит в несколько этапов: сначала открываем его, тем самым получая дескриптов, потом вызываем сисколл (например write), который запишет текст в этот дескриптор.

Отвечая на первый вопрос: stdout открывать не надо и искать его тоже не надо: это "виртуальный" файл, который автоматически открывается для каждой программы с дескриптором 1.

Отвечая на второй вопрос: данные в stdout записываются ровно так же, как и в любой файл.

Эта информация универсальна, потому что так или иначе любой вывод текста в консоль сводится к этому механизму.

Переходя к виртуальным машинам, нужно сразу вспомнить, что они сами тоже написаны на каком-то языке. Вообще говоря, для вывода текста в консоль виртуальная машина может просто использовать средства языка, на котором она реализованна, но этот вариант не так интересен.

Сами по себе виртуальные машины обычно реализованы как интерпретатор/JIT-компилятор (а иногда даже AOT-компилятор!) байт-кода. Обычно под вывод не выделяют отдельную инструкцию. В виртуальных машинах часто присутствует механизм, позволяющий взаимодействовать с нативным кодом (то есть кодом на низкоуровневых языках, собранным в бинарник), так называемый native function interface. Этот механизм, конечно, работает во многом усилиями языка, на котором реализована ВМ, и именно он позволяет взять и вызвать функцию, которая под капотом уже вызывает соответствующий сисколл.

Объяснение, конечно, относительно детальное, но всё ещё сильное упрощённое. Надеюсь, интересующимся я помог.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
hint000
@hint000
у админа три руки
как это работает именно в случае с языками по типу Java или C#
Это запрятано в библиотечных функциях и программист может не задумываться о том, как оно работает. Вызываете стандартную функцию вывода и она делает всю работу. Примеры:
https://ru.wikipedia.org/wiki/Printf
https://prog-cpp.ru/cpp-std/
записать данные в него можно используя API POSIX
Может быть и можно. Но на самом-то деле все используют те же самые библиотечные функции.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы