Новый процесс создается в UNIX только путем системного вызова fork. Процесс, сделавший вызов fork, называется родительским, а вновь созданный процесс - порожденным. Новый процесс является точной копией родительского. При порождении (разветвлении) процесса проверяется, достаточно ли памяти и места в таблице процессов для данного процесса. Если да, то образ текущего процесса копируется в новый образ процесса, и в таблице процессов возникает новый элемент. Новому процессу присваивается новый уникальный идентификатор (PID). Когда изменение таблицы процессов ядра завершается, процесс добавляется к списку процессов, готовых к выполнению.
Порожденный процесс наследует от родительского процесса следующие основные характеристики:
- Способы обработки сигналов (адреса функций обработки сигналов).
- Реальные и эффективные идентификаторы пользователя и группы.
- Значение поправки приоритета.
- Все присоединенные разделяемые сегменты памяти.
- Идентификатор группы процессов.
- Терминальную линию.
- Текущий каталог.
- Корневой каталог.
- Маску создания файлов (umask).
- Ограничения ресурсов (ulimit).
Порожденный процесс отличается от родительского процесса следующими основными характеристиками:
- имеет свой уникальный идентификатор.
- имеет другой идентификатор родительского процесса, равный идентификатору породившего процесса.
- имеет свои собственные копии дескрипторов файлов (в частности, стандартных потоков), открытых родительским процессом. Каждый дескриптор файла порожденного процесса имеет первоначально такое же значение текущей позиции в файле, что и соответствующий родительский. У порожденного процесса обнуляются счетчики времени, потраченного системой для его обслуживания.
Родительский и дочерний процессы имеют свои собственные образы. При этом код одной и той же программы может использоваться несколькими процессами. В этом случае совместно используется сегмент кода в памяти, но в остальном процессы изолированы друг от друга и имеют различные сегменты данных и стека.
После того, как дочерний процесс начинает работу, выполняется системный вызов exec(), задающий имя команды в качестве параметра. Его задачи: