Разработка ядра Linux | страница 43



для уменьшения счетчика ссылок на объекты, которые отвечают файловым дескрипторам, данным по файловой системе, пространству имен и обработчикам сигналов соответственно. Если счетчик ссылок какого- либо объекта достигает значения, равного нулю, то соответствующий объект больше не используется никаким процессом и удаляется.

• Устанавливается код завершения задания, который хранится в поле >exit_code структуры >task struct. Значение этого кода передается как аргумент функции >exit() или задается тем механизмом ядра, из-за которого процесс завершается.

• Вызывается функция >exit_notify(), которая отправляет сигналы родительскому процессу завершающегося задания и назначает новый родительский процесс (reparent) для всех порожденных завершающимся заданием процессов, этим процессом становится или какой-либо один поток из группы потоков завершающегося процесса, или процесс >init. Состояние завершающегося процесса устанавливается в значение >TASK_ZOMBIE.

• Вызывается функция >schedule() для переключения на новый процесс (см. главу 4, "Планирование выполнения процессов"). Поскольку процесс в состоянии >TASK_ZOMBIE никогда не планируется на выполнение, этот код является последним, который выполняется завершающимся процессом.

Исходный код функции >do_exit() описан в файле >kernel/exit.c.

К этому моменту освобождены все объекты, занятые задачей (если они используются только этой задачей). Задача больше не может выполняться (действительно, у нее больше нет адресного пространства, в котором она может выполняться), а кроме того, состояние задачи — >TASK_ZOMBIE Единственные области памяти, которые теперь занимает процесс, — это стек режима ядра и слябовый объект, соответственно содержащие структуры >thread_info и >task_struct.

Задание завершено настолько, насколько остается возможность передать необходимую информацию родительскому процессу.

Удаление дескриптора процесса

После возврата из функции >do_exit() дескриптор завершенного процесса все еще существует в системе, но процесс находится в состоянии >TASK_ZOMBIE и не может выполняться. Как уже рассказывалось выше, это позволяет системе получить информацию о порожденном процессе после его завершения. Следовательно, завершение процесса и удаление его дескриптора происходят в разные моменты времени. После того как родительский процесс получил информацию о завершенном порожденном процессе, структура >task_struct порожденного процесса освобождается.

Семейство функций