Процесс (информатика)

Материал из Википедии — свободной энциклопедии
Перейти к: навигация, поиск
Статусы процессов в современных ОС.

Проце́сс — программа, которая выполняется в текущий момент. Стандарт ISO 9000:2000 определяет процесс как совокупность взаимосвязанных и взаимодействующих действий, преобразующих входящие данные в исходящие.

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

Также, процессом называют выполняющуюся программу и все её элементы: адресное пространство, глобальные переменные, регистры, стек, открытые файлы и т. д.

Представление процесса[править | править вики-текст]

Обычно, процесс в вычислительной системе представлен (также говорят, «владеет») следующими ресурсами:

  • памятью (обычно некоторой областью виртуальной памяти), которая включает в себя:
    • исполняемый код;
    • входные и выходные данные процесса;
    • стек вызовов (для отслеживания активных подпрограмм);
    • кучу для хранения промежуточных результатов вычислений, генерируемых во время выполнения;
Контекст текущего процесса выгружается в память, когда выполняется переключение на другой процесс[1].

Операционная система хранит большую часть информации о процессах в таблице процессов.

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

Для снижения вероятности влияния процессов друг на друга и вероятности отказа системы (например, взаимных блокировок или пробуксовки) операционная система обеспечивает изоляцию процессов и выделяет необходимые им ресурсы. Также операционная система предоставляет механизмы для взаимодействия процессов безопасными и предсказуемыми способами.

Представление процесса в памяти[править | править вики-текст]

В данном разделе рассмотрено представление процесса в памяти операционной системы Linux и архитектуры x86. Подобное представление мало отличается от многих других многозадачных операционных систем и архитектур. Например в amd64, наследнике x86, стек вызовов точно так же растёт сверху вниз, но размер адресного пространства увеличен до 248 байт.[2]

Представление программы в памяти в пространстве пользователя

Linux использует плоскую модель памяти, и поэтому в данной архитектуре каждому процессу доступно 232 байт памяти. Вся виртуальная память делится на пространство пользователя и пространство ядра. Пространство ядра занимает один гигабайт памяти, начиная с самого старшего адреса. Всё остальное пространство, то есть, три гигабайта отведено под пространство пользователя.

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

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

В области неинициализированных данных, как правило, хранятся глобальные переменные.

Куча (heap) используется для выделения памяти во время работы программы. В Linux для этого существует системный вызов mmap.

Область стека используется для вызова процедур.

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

Динамически подключаемые библиотеки и отображения файлов располагаются между стеком и кучей.

Иерархия процессов[править | править вики-текст]

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

Unix[править | править вики-текст]

Unix - одна из первых многозадачных ОС. Каждый процесс имеет уникальный числовой идентификатор PID. Процессы в ней имеют древовидную иерархию, где корнем является процесс init c PID 1. Новый процесс можно создать системным вызовом fork, он будет являться точной копией процесса родителя. Любой процесс кроме init всегда имеет процесс родитель (атрибут PPID (англ. Parent PID)); процессы, родитель которых завершил свою работу становятся дочерними процессами init.

Процессы также объединяются в группы. За управление идентификатором группы (PGID) отвечают системные вызовы setpgid и getpgid. PGID равен PID'у лидера группы. Процесс потомок наследует группу от родителя. Группы используются для управления заданиями.

Группы процессов объединяются в сессии. За создание новой сессии отвечает системный вызов setsid. Процессы из одной группы не могут принадлежать разным сессиям. Поэтому лидер группы не может стать лидером сессии: при создании сессии дочерний процесс автоматически становится лидером сессии и лидером новой группы. Сессии используются для отслеживания всех процессов, запущенных после входа пользователя.

Каждая сессия может иметь не более одного управляющего терминала. Эмулятор терминала имеет дочерним процессом оболочку команд (чаще всего bash или sh), которая перед запуском становится лидером новой сессии и устанавливает себе управляющим терминал.

Создание процесса[править | править вики-текст]

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

Состояния процесса[править | править вики-текст]

Процесс, помимо главного рабочего состояния, может находиться в других состояниях, например ожидания.

Linux[править | править вики-текст]

Граф переходов

Процесс в ОС Linux может находиться в одном из следующих состояний:

  • R (running/runnable) — процесс исполняется либо ожидает своей очереди исполняться;
  • D — непрерываемый сон — процесс ожидает определённого события;
  • S — прерываемый сон — процесс ожидает определённого события либо сигнала;
  • T — остановка — процесс приостановлен, например, отладчиком;
  • Z (zombie) — процесс уже завершился, но ещё не передал родительскому процессу свой код возврата.

Завершение процесса[править | править вики-текст]

Минимум 2 этапа завершения:

  1. Процесс удаляется из всех очередей планирования, то есть ОС больше не планирует выделение каких-либо ресурсов процессу,
  2. Сбор статистики о потреблённых процессом ресурсах с последующим удалением его из памяти.

Причины завершения процесса:

  • Обычный выход,
  • Выход по исключению или ошибке,
  • Недостаточный объём памяти,
  • Превышение лимита отведённого программе времени,
  • Выход за пределы отведённой области памяти,
  • Неверная команда (данные программы интерпретируются как инструкции для процессора),
  • Ошибка защиты (выполнение непривилегированной команды),
  • Завершение родительского процесса,
  • Ошибка ввода-вывода,
  • Вмешательство оператора.

Примечания[править | править вики-текст]

  1. Э. Танненбаум. Современные операционные системы = Modern Operating Systems. — 2-е изд. — СПб.: Питер, 2002. — С. 59, 97. — 1040 с. — ISBN 5-318-00299-4.
  2. AMD Corporation. Volume 2: System Programming (PDF). AMD64 Architecture Programmer's Manual. AMD Corporation (December 2016). Проверено 25 марта 2017.

Литература[править | править вики-текст]