#новичкам
Сегодня поподробнее поговорим про процессы, зачем они нужны, какую роль играют и какой у них жизненный цикл. Но опять же в дебри лезть не будет, погрузимся только в важные моменты.
Процессы, как и все в этом мире, появилось в результате эволюции ОС и их подходов к управлению программами. Главный вызов - организация мультизадачности. Хочется, чтобы на одном компьютере могли исполняться множество программ.
Процесс - это абстракция ОС, предназначенная для удобного, безопасного и независимого исполнения кода различных программ на одном компьютере.
Пожалуй, самое важное здесь - процесс нужен для изоляции исполнения одной программы от исполнения другой. Изоляция достигается несколькими механизмами, обсудим самые важные:
⚡️ Механизм виртуальной памяти. У каждого процесса свое независимое ни от кого виртуальное пространство адресов. Все операции с памятью через ОС. Так она контролирует, чтобы один процесс не мог всякими неблагонадежными способами заполучить информацию из других процессов. Если он все-таки попытается что-то подобное сделать, то получит сигнал SIGSEGV.
У процессов конечно могут быть общие для доступа участки памяти(shared memory), но это делается явно и контролируемо.
⚡️Привилегии процессов. В современных ОС используется два уровня привилегии: режим ядра и пользовательский режим. Код пользовательского процесса не может выполнять привилегированные инструкции и не имеет прямого доступа к аппаратуре. Системные вызовы — единственный канал для взаимодействия с ядром, и они строго контролируются. Грубо говоря, пользовательский процесс(а это все процессы прикладных приложений) физически не может сделать ничего плохого на уровне ОС и повлиять на работу других программ.
Про изоляцию мы поняли, за счет нее обеспечивается безопасность железа и других программ. Но у процесса есть еще набор ресурсов, с помощью которых он взаимодействует с внешним миром:
1️⃣ PID - айдишник процесса. Это уникальный номер, который ОС присваивает каждому процессу в момент его создания. PID используется для идентификации процесса: по нему можно отправить сигнал, получить информацию о процессе или управлять им.
2️⃣ Когда программе нужно открыть файл, установить сетевое соединение или создать объект синхронизации, она обращается к ОС. В ответ ОС выдаёт дескриптор — небольшой идентификатор, который становится «пропуском» для работы с этим ресурсом. Практически любой ресурс, принадлежащий процессу, может быть представлен дескриптором: файлы, сокеты, каналы, устройства, таймеры и тд.
3️⃣ Переменные окружения. Это именованные строковые значения, которые ОС передаёт каждому процессу при его запуске. Они описывают среду, в которой работает программа: где искать исполняемые файлы, где хранить временные данные. Секреты для приложения также часто передаются через переменные окружения.
4️⃣ Память. Хоть процесс распоряжается виртуальной памятью, она все равно маппится на физические адреса. В памяти процесса содержатся стеки потоков, куча, код самой программы.
Хоть процессы и изолированы, но если в одном из них утекает память или дескрипторы, страдают от этого все.
Теперь чуть-чуть-чуть про цикл жизни
В Unix-подобных системах процесс создаётся системным вызовом
fork(). Он копирует текущий процесс в новый и ему присваивается свой уникальный PID. Оба процесса продолжают выполнение с инструкции, следующей сразу после вызова fork(). При этом в родительском потоке возвращается pid ребенка, а в ребенке возвращается 0:int main() {
pid_t pid = fork();
if (pid == 0) {
printf("Child: PID=%d, parent=%d\n", getpid(), getppid());
} else if (pid > 0) {
printf("Parent: PID=%d, child=%d\n", getpid(), pid);
} else {
perror("fork failed");
return 1;
}
return 0;
}Процесс может завершиться самостоятельно, вызвав системный вызов
exit(), или быть принудительно убитым сигналом (SIGKILL, SIGSEGV и др.). При завершении ядро освобождает все занятые ресурсы процесса и удаляет информацию о нем в своих структурах.#OS #goodoldc