Открыть сервис

Исполнение (execution)

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

История

Понятие исполнения кода зародилось с появлением первых программируемых вычислительных машин в середине XX века. В 1940-х годах, с созданием машин на релейной и ламповой основе (например, ENIAC), программы вводились вручную с помощью переключателей и перфолент, а исполнение представляло собой последовательное срабатывание реле или электронных ламп по заданному алгоритму. С развитием архитектуры фон Неймана, предложенной в 1945 году, программы стали храниться в памяти как данные, что позволило автоматизировать процесс исполнения: центральный процессор (ЦП) последовательно считывал инструкции из памяти и выполнял их.

В 1950-1960-х годах, с появлением первых операционных систем (например, GM-NAA I/O), исполнение стало управляться системой: программы загружались в память, запускались, а по завершении возвращали управление операционной системе. В 1970-х годах, с развитием многозадачности (например, в UNIX), исполнение стало возможным для нескольких процессов одновременно, что потребовало механизмов планирования и переключения контекста. В 1990-х годах, с распространением интерпретируемых языков (Python, JavaScript), исполнение стало включать этап интерпретации, когда код преобразуется в машинные инструкции «на лету».

Архитектура исполнения

Процессор и цикл выполнения

Основой исполнения является цикл «выборка-декодирование-исполнение» (fetch-decode-execute cycle), выполняемый центральным процессором. Процесс включает три этапа:

  1. Выборка (fetch) — извлечение инструкции из оперативной памяти по адресу, хранящемуся в счётчике команд (PC, Program Counter).
  2. Декодирование (decode)преобразование машинного кода инструкции в управляющие сигналы для арифметико-логического устройства (АЛУ) и других блоков.
  3. Исполнение (execute) — выполнение операции (например, сложение, чтение из памяти, переход).

В современных процессорах (например, x86-64, ARM) цикл усложнён за счёт конвейерной обработки, суперскалярности и спекулятивного исполнения, что позволяет выполнять несколько инструкций одновременно.

Среда исполнения

Программа исполняется в определённой среде, которая включает:

  • Операционную систему — управляет ресурсами (память, процессорное время, ввод-вывод) и предоставляет системные вызовы.
  • Виртуальную машину — программная среда, эмулирующая аппаратное обеспечение (например, Java Virtual Machine, JVM, исполняет байт-код).
  • Интерпретатор — программа, которая непосредственно выполняет код на высокоуровневом языке (например, CPython для Python, V8 для JavaScript).

Виды исполнения

По способу выполнения

  • Последовательное исполнение — инструкции выполняются одна за другой в порядке, заданном программой. Характерно для однопоточных процессов.
  • Параллельное исполнение — одновременное выполнение нескольких инструкций на разных процессорных ядрах или в разных потоках. Реализуется через многопоточность и многопроцессность.
  • Конвейерное исполнение — разбиение инструкции на этапы, которые обрабатываются параллельно на разных стадиях конвейера. Увеличивает пропускную способность процессора.

По типу кода

  • Исполнение машинного кода — непосредственное выполнение инструкций процессором. Требует компиляции исходного кода в двоичный формат (например, C, C++, Rust).
  • Исполнение байт-кода — выполнение промежуточного представления кода виртуальной машиной (например, Java, .NET, Python). Обеспечивает переносимость между платформами.
  • Интерпретируемое исполнение — выполнение исходного кода без предварительной компиляции, с построчным преобразованием в машинные инструкции (например, JavaScript, PHP, Ruby).
  • JIT-компиляция (Just-In-Time) — компиляция байт-кода или интерпретируемого кода в машинный код непосредственно во время исполнения для повышения производительности (например, в Java HotSpot, V8).

По режиму работы

  • Интерактивное исполнение — программа выполняется в режиме диалога с пользователем, ожидая ввода данных (например, REPL-цикл в Python, командная строка).
  • Пакетное исполнение — программа выполняется без участия пользователя, обрабатывая заранее заданные данные (например, пакетные файлы в Windows, скрипты cron в UNIX).
  • Фоновое исполнение — процесс выполняется без привязки к терминалу, часто в виде службы или демона (например, веб-сервер Apache, системный процесс).

Жизненный цикл исполнения

Процесс исполнения программы в операционной системе включает несколько этапов:

  1. Загрузка (loading) — программа (исполняемый файл) загружается в оперативную память из хранилища (диска, сети). Операционная система выделяет адресное пространство, загружает код, данные и библиотеки.
  2. Инициализация (initialization) — настройка среды: создание стеков, инициализация глобальных переменных, запуск конструкторов (в языках с поддержкой ООП).
  3. Выполнение (running) — процессор начинает выполнять инструкции с точки входа (например, функция main в C/C++). Управление передаётся между инструкциями, функциями и модулями.
  4. Приостановка и возобновление — в многозадачных системах процесс может быть приостановлен (например, при ожидании ввода-вывода) и возобновлён планировщиком операционной системы.
  5. Завершение (termination) — программа завершает выполнение по достижении конца кода, по команде exit или при возникновении фатальной ошибки. Операционная система освобождает ресурсы (память, файловые дескрипторы).

Контекст исполнения

Контекст исполнения — это набор данных, необходимых для возобновления выполнения процесса или потока после прерывания. Включает:

  • Регистры процессора — счётчик команд, регистры общего назначения, флаги состояния.
  • Стек вызовов — адреса возврата, локальные переменные, параметры функций.
  • Таблицы страниц — отображение виртуальной памяти на физическую.
  • Дескрипторы ресурсов — открытые файлы, сокеты, каналы.

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

Безопасность исполнения

Исполнение кода сопряжено с рисками, связанными с некорректной работой или злонамеренными действиями. Основные аспекты безопасности:

  • Ошибки времени исполнения — деление на ноль, выход за границы массива, переполнение буфера. Могут приводить к аварийному завершению или уязвимостям.
  • Вредоносное исполнение — выполнение кода, полученного из ненадёжных источников (например, через уязвимости в браузере, макросы в документах). Для защиты применяются sandbox-изоляция, контроль целостности кода (например, подписи), ограничение прав (например, непривилегированные пользователи).
  • Управление памятью — утечки памяти, двойное освобождение, использование после освобождения (use-after-free). В современных языках (Java, C#, Rust) применяются автоматическое управление памятью (сборщик мусора) или механизмы владения (ownership).
  • Спектральные атаки — уязвимости, возникающие из-за спекулятивного исполнения в процессорах (например, Spectre, Meltdown). Требуют аппаратных и программных исправлений (микрокоды, патчи ядра).

Применение

Исполнение кода лежит в основе всех компьютерных систем:

  • Операционные системы — исполняют ядро, драйверы, системные службы и пользовательские приложения.
  • Веб-технологии — серверные скрипты (PHP, Node.js) и клиентские скрипты (JavaScript) исполняются на серверах и в браузерах.
  • Научные вычисления — высокопроизводительные вычисления (HPC) исполняют параллельные программы на кластерах и суперкомпьютерах.
  • Встраиваемые системы — микроконтроллеры исполняют прошивки (firmware) для управления устройствами (бытовая техника, автомобили, промышленное оборудование).
  • Игровые движки — исполняют игровую логику, рендеринг графики и физическое моделирование в реальном времени.

Интересные факты

  • В 1970-х годах концепция «исполнения кода» была расширена появлением интерпретаторов, что позволило создавать переносимые программы (например, язык BASIC).
  • Современные процессоры Intel Core и AMD Ryzen могут выполнять до 6-8 инструкций за такт благодаря суперскалярной архитектуре.
  • В 2018 году уязвимости Spectre и Meltdown затронули миллиарды устройств, выявив фундаментальные проблемы в спекулятивном исполнении.
  • В операционной системе Linux процесс исполнения может быть отслежен с помощью системного вызова ptrace, используемого в отладчиках (например, GDB) и инструментах трассировки (strace).

Источники

  • Таненбаум Э., Бос Х. «Современные операционные системы». 4-е издание. — СПб.: Питер, 2015.
  • Хеннесси Дж., Паттерсон Д. «Архитектура компьютера и проектирование компьютерных систем». 5-е издание. — М.: Вильямс, 2014.
  • Intel Corporation. «Intel 64 and IA-32 Architectures Software Developer’s Manual». Volume 1-3, 2023.
  • Stallings W. «Operating Systems: Internals and Design Principles». 9th Edition. — Pearson, 2017.
  • Документация по ядру Linux (kernel.org) — раздел «Process Management» и «Memory Management».

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →