• После того как порожденный процесс в первый раз запущен, родительский процесс, вместо того чтобы возвратиться из функции copy_process
vfork_done.• При выполнении порожденным процессом функции mm_release
vfork_done не равно NULL, родительский процесс получает указанный выше сигнал.• При возврате в функцию do_fork
Если все прошло так, как запланировано, то теперь порожденный процесс выполняется в новом адресном пространстве, а родительский процесс — в первоначальном адресном пространстве. Накладные расходы меньше, но реализация не очень привлекательна.
Реализация потоков в ядре Linux
Многопоточность — это популярная сегодня программная абстракция. Она обеспечивает выполнение нескольких потоков в совместно используемом адресном пространстве памяти. Потоки также могут совместно использовать открытые файлы и другие ресурсы. Многопоточность используется для
Реализация потоков в операционной системе Linux уникальна. Для ядра Linux не существует отдельной концепции потоков. В ядре Linux потоки реализованы так же, как и обычные процессы. В ОС Linux нет никакой особенной семантики для планирования выполнения потоков или каких-либо особенных структур данных для представления потоков. Поток— это просто процесс, который использует некоторые ресурсы совместно с другими процессами. Каждый поток имеет структуру task_struct
В этом смысле Linux отличается от других операционных систем, таких как Microsoft Windows или Sun Solaris, которые имеют
Допустим, у нас есть процесс, состоящий из четырех потоков. В операционных системах с явной поддержкой потоков должен существовать дескриптор процесса, который далее указывает на четыре потока. Дескриптор процесса описывает совместно используемые ресурсы, такие как адресное пространство и открытые файлы. Потоки описываются ресурсами, которые принадлежат только им. В ОС 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
clone и их эффект.Таблица 3.1
. Флаги системного вызова clone