Чтение онлайн

на главную - закладки

Жанры

Разработка ядра Linux
Шрифт:

• Устанавливается флаг

PF_EXITING
в поле
flags
структуры
task struct
.

• Вызывается функция

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

• Если включена возможность учета системных ресурсов, занятых процессами (BSD process accounting), то вызывается функция

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

• Вызывается функция

__exit_mm
для освобождения структуры
mm_struct
, занятой
процессом. Если эта структура не используется больше ни одним процессом (другими словами, не является разделяемой), то она освобождается совсем.

• Вызывается функция

exit_sem
. Если процесс находится в очереди ожидания на освобождение семафора подсистемы IPC, то в этой функции процесс удаляется из этой очереди.

• Вызываются функции

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

• Устанавливается код завершения задания, который хранится в поле

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
порожденного процесса освобождается.

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

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

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

release_task
, которая выполняет указанные ниже операции.

• Вызывается функция

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

• Вызывается функция

unhash_process
для удаления процесса из хеш-таблицы идентификаторов процессов
pidhash
и удаления задачи из списка задач.

• Если задача была в состоянии трассировки (ptrace), то родительским для нее снова назначается первоначальный родительский процесс и задача удаляется из списка задач, которые находятся в состоянии трассировки (ptrace) данным процессом.

• В конце концов вызывается функция

put_task_struct
для освобождения страниц памяти, содержащих стек ядра процесса и структуру
thread_info
, a также освобождается слябовый кэш, содержащий структуру
task_struct
.

На данном этапе дескриптор процесса, а также все ресурсы, которые принадлежали только этому процессу, освобождены.

Дилемма "беспризорного" процесса

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

init
. При выполнении функции
do_exit
вызывается функция
notify_parent
, которая в свою очередь вызывает
forget_original_parent
для осуществления переназначения родительского процесса (reparent), как показано ниже.

struct task_struct *p, *reaper = father;

struct list_head *list;

if (father->exit_signal != -1)

 reaper = prev_thread(reaper);

else

 reaper = child_reaper;

if (reaper == father)

 reaper = child_reaper;

Этот программный код присваивает переменной reaper указатель на другое задание в группе потоков данного процесса. Если в этой группе потоков нет другого задания, то переменной

reaper
присваивается значение переменной
child_reaper,
которая содержит указатель на процесс
init
. Теперь, когда найден подходящий родительский процесс, нужно найти все порожденные процессы и установить для них полученное значение родительского процесса, как показано ниже.

Поделиться:
Популярные книги

Печать Пожирателя

Соломенный Илья
1. Пожиратель
Фантастика:
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Печать Пожирателя

Привет из Загса. Милый, ты не потерял кольцо?

Лисавчук Елена
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Привет из Загса. Милый, ты не потерял кольцо?

Мастер 2

Чащин Валерий
2. Мастер
Фантастика:
фэнтези
городское фэнтези
попаданцы
технофэнтези
4.50
рейтинг книги
Мастер 2

Нечто чудесное

Макнот Джудит
2. Романтическая серия
Любовные романы:
исторические любовные романы
9.43
рейтинг книги
Нечто чудесное

Клан

Русич Антон
2. Долгий путь домой
Фантастика:
боевая фантастика
космическая фантастика
5.60
рейтинг книги
Клан

Имя нам Легион. Том 3

Дорничев Дмитрий
3. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 3

Запасная дочь

Зика Натаэль
Фантастика:
фэнтези
6.40
рейтинг книги
Запасная дочь

Убивать чтобы жить 7

Бор Жорж
7. УЧЖ
Фантастика:
героическая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 7

У врага за пазухой

Коваленко Марья Сергеевна
5. Оголенные чувства
Любовные романы:
остросюжетные любовные романы
эро литература
5.00
рейтинг книги
У врага за пазухой

Кодекс Охотника. Книга XXI

Винокуров Юрий
21. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XXI

Генерал Скала и ученица

Суббота Светлана
2. Генерал Скала и Лидия
Любовные романы:
любовно-фантастические романы
6.30
рейтинг книги
Генерал Скала и ученица

Оцифрованный. Том 1

Дорничев Дмитрий
1. Линкор Михаил
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Оцифрованный. Том 1

Его маленькая большая женщина

Резник Юлия
Любовные романы:
современные любовные романы
эро литература
8.78
рейтинг книги
Его маленькая большая женщина

Хуррит

Рави Ивар
Фантастика:
героическая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Хуррит