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

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

Жанры

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

В этом смысле Linux отличается от других операционных систем, таких как Microsoft Windows или Sun Solaris, которые имеют явные средства поддержки потоков в ядре (в этих системах иногда потоки называются процессами с быстрым переключением контекста, lightweight process). Название "процесс с быстрым переключением контекста" показывает разницу между философией Linux и других операционных систем. Для остальных операционных систем потоки— это абстракция, которая обеспечивает облегченные, более быстрые для исполнения сущности, чем обычные тяжелые процессы. Для операционной системы Linux потоки — это просто способ совместного использования ресурсов несколькими процессами (которые и так имеют достаточно малое время переключения контекста) [18] .

18

Как

пример можно привести тесты по измерению времени создания процессов (и даже потоков) и операционной системе Linux по сравнению с другими операционными системами. Результаты очень хорошие.

Допустим, у нас есть процесс, состоящий из четырех потоков. В операционных системах с явной поддержкой потоков должен существовать дескриптор процесса, который далее указывает на четыре потока. Дескриптор процесса описывает совместно используемые ресурсы, такие как адресное пространство и открытые файлы. Потоки описываются ресурсами, которые принадлежат только им. В ОС Linux, наоборот, существует просто четыре процесса и, соответственно, четыре обычные структуры

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

Потоки создаются так же, как и обычные задания, за исключением того, что в системный вызов

clone
передаются флаги с указанием, какие ресурсы должны использоваться совместно:

clone(CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND, 0);

Результат выполнения показанного кода будет таким же, как и при выполнении обычного вызова

fork
, за исключением того, что адресное пространство, ресурсы файловой системы, дескрипторы файлов и обработчики сигналов останутся общими. Другими словами, новая задача, так же как и родительский процесс, — обычные потоки. В отличие от этого, обычный вызов
fork
может быть реализован следующим образом:

clone(SIGCHLD, 0);

а вызов

vfork
в таком виде:

clone(CLONE_VFORK | CLONE_VM | SIGCHLD, 0);

Флаги, которые передаются в системный вызов

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

Таблица 3.1. Флаги системного вызова clone

Флаг Описание
CLONE_FILES
Родительский и порожденный процессы совместно используют открытые файлы
CLONE_FS
Родительский и порожденный процессы совместно используют информацию о файловой системе
CLONE_IDLETASK
Установить значение PID в нуль (используется только для холостых (idle) задач)
CLONE_NEWNS
Создать новое пространство имен для порожденной задачи
CLONE_PARENT
Родительский процесс вызывающего процесса становится родительским и для порожденного
CLONE_PTRACE
Продолжить трассировку и для порожденного процесса
CLONE_SETTID
Возвратить значение идентификатора TID в пространство пользователя
CLONE_SETTLS
Для порожденного процесса создать новую область локальных данных потока (thread local storage, TLS)
CLONE_SIGHAND
У порожденного и родительского процессов будут общие обработчики сигналов
CLONE_SYSVSEM
У родительского и порожденного процессов будет общая семантика обработки флага
SEM_UNDO
для семафоров System V
CLONE_THREAD
Родительский и порожденный процессы будут принадлежать одной группе потоков
CLONE_VFORK
Использовать
vfork
: родительский процесс будет
находиться а приостановленном состоянии, пока порожденный процесс не возобновит его работу
CLONE_UNTRACED
Запретить родительскому процессу использование флага
CLONE_PTRACE
для порожденного процесса
CLONE_STOP
Запустить процесс в состоянии
TASK_STOPPED
CLONE_CHILD_CLEARTID
Очистить идентификатор TID для порожденного процесса
CLONE_CHILD_SETTID
Установить идентификатор TID для порожденного процесса
CLONE_PARENT_SETTID
Установить идентификатор TID для родительского процесса
CLONE_VM
У порожденного и родительского процессов будет общее адресное пространство

Потоки в пространстве ядра

Часто в ядре полезно выполнить некоторые операции в фоновом режиме. В ядре такая возможность реализована с помощью потоков пространства ядра (kernel thread) — обычных процессов, которые выполняются исключительно в пространстве ядра. Наиболее существенным отличием между потоками пространства ядра и обычными процессами является то, что потоки в пространстве ядра не имеют адресного пространства (значение указателя

mm
для них равно
NULL
). Эти потоки работают только в пространстве ядра, и их контекст не переключается в пространство пользователя. Тем не менее потоки в пространстве ядра планируются и вытесняются так же, как и обычные процессы.

В ядре Linux потоки пространства ядра выполняют определенные задания, наиболее часто используемые, — это pdfush и ksoftirq. Эти потоки создаются при загрузке системы другими потоками пространства ядра. В действительности поток в пространстве ядра может быть создан только другим потоком, работающим в пространстве ядра. Интерфейс для запуска нового потока в пространстве ядра из уже существующего потока следующий:

int kernel_thread(int (*fn)(void*), void* arg, unsigned long flags);

Новая задача создается с помощью обычного системного вызова

clone
с соответствующими значениями флагов, указанными в параметре flags. При возврате из системного вызова родительский поток режима ядра завершается и возвращает указатель на структуру
task_struct
порожденного процесса. Порожденный процесс выполняет функцию, адрес которой указан в параметре
fn
, в качестве аргумента этой функции передается параметр
arg
. Для указания обычных флагов потоков пространства ядра существует флаг
CLONE_KERNEL
, который объединяет в себе флаги
CLONE_FS
,
CLONE_FILES
и
CLONE_SIGHAND
, так как большинство потоков пространства ядра должны указывать эти флаги в параметре
flags
.

Чаще всего поток пространства ядра продолжает выполнять свою функцию вечно (или, по крайней мере, до перегрузки системы, но когда она произойдет в случае ОС Linux- неизвестно). Функция потока обычно содержит замкнутый цикл, в котором поток пространства ядра по необходимости возобновляет выполнение, исполняет свои обязанности и снова переходит в приостановленное состояние.

В следующих главах более детально будут рассмотрены конкретные примеры потоков пространства ядра.

Завершение процесса

Как это ни грустно, но любой процесс в конечном итоге должен завершиться. Когда процесс завершается, ядро должно освободить ресурсы, занятые процессом, и оповестить процесс, который является родительским для завершившегося, о том, что его порожденный процесс, к сожалению, "умер".

Обычно уничтожение процесса происходит тогда, когда процесс вызывает системный вызов

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

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

Государь

Кулаков Алексей Иванович
3. Рюрикова кровь
Фантастика:
мистика
альтернативная история
историческое фэнтези
6.25
рейтинг книги
Государь

Гром Раскатного. Том 3

Володин Григорий Григорьевич
3. Штормовой Предел
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Гром Раскатного. Том 3

Последний реанорец. Том III

Павлов Вел
2. Высшая Речь
Фантастика:
фэнтези
попаданцы
5.25
рейтинг книги
Последний реанорец. Том III

Двойник короля 12

Скабер Артемий
12. Двойник Короля
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Двойник короля 12

Гримуар темного лорда V

Грехов Тимофей
5. Гримуар темного лорда
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Гримуар темного лорда V

Ботаник 2

Щепетнов Евгений Владимирович
2. Ботаник
Фантастика:
фэнтези
боевая фантастика
6.00
рейтинг книги
Ботаник 2

Главбухша

Романов Владислав Иванович
Любовные романы:
остросюжетные любовные романы
5.00
рейтинг книги
Главбухша

Язычник

Мазин Александр Владимирович
5. Варяг
Приключения:
исторические приключения
8.91
рейтинг книги
Язычник

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

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

Менталист. Конфронтация

Еслер Андрей
2. Выиграть у времени
Фантастика:
боевая фантастика
6.90
рейтинг книги
Менталист. Конфронтация

Лекарь Империи 8

Лиманский Александр
8. Лекарь Империи
Фантастика:
попаданцы
городское фэнтези
аниме
5.00
рейтинг книги
Лекарь Империи 8

Последний Паладин. Том 13

Саваровский Роман
13. Путь Паладина
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 13

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

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

Сирота

Шмаков Алексей Семенович
1. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
5.00
рейтинг книги
Сирота