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

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

Жанры

Разработка ядра 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
. Теперь, когда найден подходящий родительский процесс, нужно найти все порожденные процессы и установить для них полученное значение родительского процесса, как показано ниже.

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

Отморозок 3

Поповский Андрей Владимирович
3. Отморозок
Фантастика:
попаданцы
5.00
рейтинг книги
Отморозок 3

Род Корневых будет жить!

Кун Антон
1. Тайны рода
Фантастика:
фэнтези
попаданцы
аниме
7.00
рейтинг книги
Род Корневых будет жить!

На границе империй. Том 7. Часть 2

INDIGO
8. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
6.13
рейтинг книги
На границе империй. Том 7. Часть 2

Полковник Империи

Ланцов Михаил Алексеевич
3. Безумный Макс
Фантастика:
альтернативная история
6.58
рейтинг книги
Полковник Империи

Идеальный мир для Лекаря 11

Сапфир Олег
11. Лекарь
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 11

Последняя Арена 2

Греков Сергей
2. Последняя Арена
Фантастика:
рпг
постапокалипсис
6.00
рейтинг книги
Последняя Арена 2

Скрываясь в тени

Мазуров Дмитрий
2. Теневой путь
Фантастика:
боевая фантастика
7.84
рейтинг книги
Скрываясь в тени

Герцог и я

Куин Джулия
1. Бриджертоны
Любовные романы:
исторические любовные романы
8.92
рейтинг книги
Герцог и я

Владеющий

Злобин Михаил
2. Пророк Дьявола
Фантастика:
фэнтези
8.50
рейтинг книги
Владеющий

Развод с миллиардером

Вильде Арина
1. Золушка и миллиардер
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Развод с миллиардером

Паладин из прошлого тысячелетия

Еслер Андрей
1. Соприкосновение миров
Фантастика:
боевая фантастика
попаданцы
6.25
рейтинг книги
Паладин из прошлого тысячелетия

Боги, пиво и дурак. Том 6

Горина Юлия Николаевна
6. Боги, пиво и дурак
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Боги, пиво и дурак. Том 6

Бестужев. Служба Государевой Безопасности. Книга вторая

Измайлов Сергей
2. Граф Бестужев
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бестужев. Служба Государевой Безопасности. Книга вторая

Орден Багровой бури. Книга 6

Ермоленков Алексей
6. Орден Багровой бури
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Орден Багровой бури. Книга 6