Связывание и загрузка на переведенных языках

В скомпилированных языках исходный код превращается компилятором в объектный код, а различные объектные файлы (если их несколько) связаны компоновщиком и загружаются в память загрузчиком для выполнения.

Если у меня есть приложение, написанное с использованием интерпретированного языка (например, ruby ​​или python), и если исходный код разделен по файлам, когда именно эти файлы объединяются. Другими словами, когда связь сделана? Есть ли в интерпретируемых языках компоновщики и загрузчики, или переводчик все делает?

Я действительно смущен этим и не в состоянии обдумать это!! Кто-нибудь может пролить свет на это?!

2 ответа

Решение

Интерпретируемый язык - это более или менее большая конфигурация для исполняемого файла, который называется интерпретатором. Этот исполняемый файл (например, /usr/bin/python) это программа, которая на самом деле работает. Затем он читает сценарий, который должен выполнить (например, /home/alfe/bin/factorial.py) и выполняет его в простейшей форме построчно.

Во время этого процесса могут встречаться ссылки на другие файлы (другие модули, например, /usr/python/lib/math.py), а затем он будет читать и интерпретировать те.

во многих таких языках есть встроенные механизмы, позволяющие сократить накладные расходы на этот процесс путем создания версий байт-кода сценариев, которые они интерпретируют. Так что вполне может быть файл /usr/python/lib/math.pyc например, который переводчик поместил туда после первой обработки и который он может прочитать и интерпретировать быстрее, чем оригинал /usr/python/lib/math.py, Но это на самом деле не является частью концепции интерпретируемых языков¹.

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

Но в целом можно сказать, что двоичный машинный код не генерируется вообще. И ничего не связано во время компиляции. На самом деле реального времени компиляции не существует, хотя эту первую обработку входных сценариев можно назвать этапом компиляции.

Примечания:

The) Концепция интерпретации сценариев не включает ни "компиляцию" (предварительный перевод источника в более быструю для интерпретации форму), ни "кэширование" этой формы путем хранения файлов, подобных .pyc файлы. В связи с вашим вопросом, касающимся связывания и разбиения программ на несколько файлов или модулей, эти аспекты предварительной компиляции и кэширования являются лишь техническими деталями для ускорения процесса. Сама концепция такова: прочитайте одну строку входного скрипта и выполните его. Затем прочитайте следующую строку и так далее.

Ну, в Python модули загружаются и выполняются или анализируются, когда интерпретатор находит какой-либо метод или указание для этого. Там нет ссылок, но есть загрузка, конечно (когда файл запрашивается в коде).

Python делает что-то умное, чтобы улучшить его производительность. Компилируется в байт-код (.pyc файлы) при первом запуске файла. Это существенно улучшает выполнение кода в следующий раз, когда модуль импортируется или выполняется.

Так что поведение более или менее:

  1. Файл выполнен
  2. Внутри файла интерпретатор находит ссылку на другой файл
  3. Он анализирует его и потенциально выполняет его. Это означает, что каждое определение класса, переменной или метода станет доступным во время выполнения.

И это, как процесс выполняется (очень общий). Конечно, существуют оптимизации и кэши для повышения производительности.

Надеюсь это поможет!

Другие вопросы по тегам