Ядро Linux в комментариях

Происхождение процессов: fork и __clone


Традиционные реализации Unix предоставляют только один способ создания новых процессов после того, как система запущена: системный вызов fork. (Если читателей интересует происхождение первого процесса, то оно описано в .) Когда процесс вызывает функцию fork, он делится на два— подобно развилке дороги — после чего родительский и дочерний процессы вольны следовать различными путями. Непосредственно после выполнения функции fork родительский и дочерний процессы почти идентичны — все их переменные имеют одинаковые значения, у них открыты одни и те же файлы и т.п. Но если родительский процесс изменяет значение переменной, дочерний процесс не видит этого изменения и наоборот. Дочерний процесс — это копия родительского процесса (по крайней мере, вначале), но они не используют ресурсы совместно.

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

Попутно следует отметить, что с помощь функции kernel_thread (строка ) ядро создает несколько задач для собственного использования. Пользователи никогда не вызывают эту функцию — в действительности они и не могут это сделать; она предназначена исключительно для создания специальных процессов, таких как kswapd (он освещен в ), которые по существу являются частями ядра, для удобства обрабатываемыми в качестве задач. Создаваемые функцией kernel_thread задачи имеют некоторые необычные свойства, которые не будут подробно освещаться (например, они не могут быть предварительно освобождены), но на данном этапе главное запомнить, что функция kernel_thread использует подпрограмму do_fork для выполнения всей рутинной работы. Таким образом, строго говоря, на практике даже эти специальные процессы создаются так же, как обычные.



Содержание раздела