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- неизвестно). Функция потока обычно содержит замкнутый цикл, в котором поток пространства ядра по необходимости возобновляет выполнение, исполняет свои обязанности и снова переходит в приостановленное состояние.
Читать дальше