Jump to content

вилка (системный вызов)

(Перенаправлено из Fork (операционная система) )

В вычислительной технике , особенно в контексте операционной системы Unix и ее аналогов , разветвление — это операция, посредством которой процесс создает копию самого себя. Это интерфейс, который необходим для соответствия стандартам POSIX и единой спецификации UNIX . Обычно он реализуется как библиотеки C стандартной для fork, clone или других системных вызовов ядра оболочка . Форк — это основной метод создания процессов в Unix-подобных операционных системах.

В многозадачных операционных системах процессам (выполняемым программам) необходим способ создания новых процессов, например, для запуска других программ. Fork и его варианты обычно являются единственным способом сделать это в Unix-подобных системах. Чтобы процесс начал выполнение другой программы, он сначала создает свою копию. Затем копия, называемая « дочерним процессом », вызывает системный вызов exec для наложения себя на другую программу: она прекращает выполнение своей предыдущей программы в пользу другой.

Операция fork создает отдельное адресное пространство для дочернего элемента . Дочерний процесс имеет точную копию всех сегментов памяти родительского процесса. В современных вариантах UNIX, которые следуют модели виртуальной памяти из SunOS -4.0, копирования при записи реализована семантика , и физическая память не требует фактического копирования. Вместо этого страницы виртуальной памяти в обоих процессах могут ссылаться на одни и те же страницы физической памяти до тех пор, пока один из них не запишет такую ​​страницу: тогда она копируется. Эта оптимизация важна в обычном случае, когда fork используется вместе с exec для выполнения новой программы: обычно дочерний процесс выполняет лишь небольшой набор действий, прежде чем он прекращает выполнение своей программы в пользу запускаемой программы. родительского элемента, если они вообще требуются и для него требуется очень мало структур данных .

Когда процесс вызывает fork, он считается родительским процессом , а вновь созданный процесс — его дочерним. После разветвления оба процесса не только запускают одну и ту же программу, но и возобновляют выполнение, как если бы оба процесса вызвали системный вызов. вызова, Затем они могут проверить возвращаемое значение чтобы определить свой статус (дочерний или родительский) и действовать соответствующим образом.

Одна из самых ранних ссылок на концепцию вилки появилась в Проектирование многопроцессорной системы» « книге Мелвина Конвея , опубликованной в 1962 году. [1] Статья Конвея послужила мотивацией для реализации Л. Питером Дойчем форка в системе разделения времени GENIE , где эта концепция была заимствована Кеном Томпсоном для ее самого раннего появления. [2] в исследовательской Unix . [3] [4] Позднее Fork стал стандартным интерфейсом POSIX . [5]

Коммуникация

[ редактировать ]

Дочерний процесс начинается с копии файловых дескрипторов своего родительского процесса . [5] Для межпроцессного взаимодействия родительский процесс часто создаёт один или несколько каналов , а затем после форка процессы закрывают ненужные им концы каналов. [6]

Варианты

[ редактировать ]

Vfork — это вариант fork с тем же соглашением о вызовах и почти такой же семантикой, но его можно использовать только в ограниченных ситуациях. Он возник в 3BSD . версии Unix [7] [8] [9] первая Unix, поддерживающая виртуальную память. Он был стандартизирован POSIX, что позволяло vfork вести себя точно так же, как fork, но в версии 2004 года он был помечен как устаревший. [10] и был заменен на posix_spawn () (который обычно реализуется через vfork) в последующих редакциях.

При выполнении системного вызова vfork родительский процесс будет приостановлен до тех пор, пока дочерний процесс не завершит выполнение или не будет заменен новым исполняемым образом с помощью одного из системных вызовов семейства exec . Дочерний процесс заимствует настройку модуля управления памятью у родительского, и страницы памяти совместно используются родительским и дочерним процессами без копирования и, в частности, без копирования при записи ; семантики [10] следовательно, если дочерний процесс вносит изменения в любую из общих страниц, новая страница не будет создана, и измененные страницы также будут видны родительскому процессу. Поскольку копирование страниц абсолютно не требуется (требуется дополнительная память), этот метод представляет собой оптимизацию по сравнению с простым форком в средах полного копирования при использовании с exec. В POSIX использование vfork для любых целей, за исключением прелюдии к немедленному вызову функции из семейства exec (и некоторых других операций), приводит к неопределенному поведению . [10] Как и в случае с vfork, дочерний элемент заимствует структуры данных, а не копирует их. vfork по-прежнему быстрее, чем форк, использующий семантику копирования при записи.

System V не поддерживала этот вызов функции до появления System VR4. [ нужна ссылка ] потому что совместное использование памяти, которое это вызывает, подвержено ошибкам:

Vfork не копирует таблицы страниц, поэтому он работает быстрее, чем вилки реализация System V. Но дочерний процесс выполняется в том же физическом адресном пространстве, что и родительский процесс (до выполнения exec или выхода ) и, таким образом, может перезаписать данные и стек родительского процесса. Опасная ситуация может возникнуть, если программист неправильно использует vfork , поэтому ответственность за вызов vfork лежит на программисте. Разница между подходом System V и подходом BSD философская: должно ли ядро ​​скрывать от пользователей особенности своей реализации или оно должно предоставить опытным пользователям возможность воспользоваться преимуществами реализации для более эффективного выполнения логической функции?

Морис Дж. Бах [11]

Аналогично, справочная страница Linux для vfork настоятельно не рекомендует его использовать: [7] [ не удалось пройти проверку ] [ обсуждать ]

Очень прискорбно, что Linux возродил этот призрак из прошлого. На странице руководства BSD говорится: «Этот системный вызов будет исключен, когда будут реализованы надлежащие механизмы совместного использования системы. Пользователи не должны зависеть от семантики разделения памяти vfork(), поскольку в этом случае он станет синонимом fork(2). ."

Другие проблемы с vfork включает взаимоблокировки , которые могут возникнуть в многопоточных программах из-за взаимодействия с динамическим связыванием . [12] В качестве замены для vfork , POSIX представил Семейство функций posix_spawn , сочетающих в себе действия fork и exec. Эти функции могут быть реализованы как библиотечные процедуры с точки зрения fork , как это делается в Linux, [12] или с точки зрения vfork для лучшей производительности, как это сделано в Solaris, [12] [13] но в спецификации POSIX отмечается, что они «разработаны как операции ядра », особенно для операционных систем, работающих на ограниченном оборудовании и системах реального времени . [14]

Хотя реализация 4.4BSD избавилась от реализации vfork, в результате чего vfork имел такое же поведение, как и fork, позже он был восстановлен в операционной системе NetBSD по соображениям производительности. [8]

Некоторые встроенные операционные системы, такие как uClinux, не используют fork и реализуют только vfork, поскольку им необходимо работать на устройствах, где копирование при записи невозможно реализовать из-за отсутствия блока управления памятью.

Операционная система Plan 9 , созданная разработчиками Unix, включает в себя fork, а также вариант под названием «rfork», который позволяет детально распределять ресурсы между родительскими и дочерними процессами, включая адресное пространство (за исключением сегмента стека , который уникальные для каждого процесса), переменные среды и пространство имен файловой системы; [15] это делает его единым интерфейсом для создания как процессов, так и потоков внутри них. [16] Обе FreeBSD [17] и IRIX переняли системный вызов rfork из Plan 9, последний переименовал его в «sproc». [18]

Клонировать

[ редактировать ]

clone — это системный вызов в ядре Linux , который создает дочерний процесс, который может разделять части своего контекста выполнения с родительским. Подобно rfork FreeBSD и sproc IRIX, клон Linux был вдохновлен rfork Plan 9 и может использоваться для реализации потоков (хотя программисты приложений обычно используют интерфейс более высокого уровня, такой как pthreads , реализованный поверх клона). Функция «отдельных стеков» из Plan 9 и IRIX была опущена, поскольку (по словам Линуса Торвальдса ) она приводит к слишком большим накладным расходам. [18]

Разветвление в других операционных системах

[ редактировать ]

В первоначальном проекте операционной системы VMS (1977 г.) операция копирования с последующей мутацией содержимого нескольких конкретных адресов для нового процесса, как при разветвлении, считалась рискованной. [ нужна ссылка ] Ошибки в текущем состоянии процесса могут быть скопированы в дочерний процесс. Здесь используется метафора порождения процесса: каждый компонент структуры памяти нового процесса создается заново с нуля. Метафора появления позже была принята в операционных системах Microsoft (1993).

Компонент совместимости с POSIX VM/CMS (OpenExtensions) обеспечивает очень ограниченную реализацию fork, в которой родительский процесс приостанавливается на время выполнения дочернего процесса, а дочерний и родительский элементы используют одно и то же адресное пространство. [19] По сути, это vfork, помеченный как fork . (Это относится только к гостевой операционной системе CMS; другие гостевые операционные системы виртуальных машин, такие как Linux, предоставляют стандартные функции разветвления.)

Использование приложения

[ редактировать ]

Следующий вариант «Hello, World!» программа демонстрирует механику fork системный вызов на C. языке программирования Программа разделяется на два процесса, каждый из которых решает, какую функциональность он выполняет, на основе возвращаемого значения системного вызова fork. Шаблонный код , такой как включение заголовков, опущен.

int main(void)
{
    pid_t pid = fork();

    if (pid == -1) {
        perror("fork failed");
        exit(EXIT_FAILURE);
    }
    else if (pid == 0) {
        printf("Hello from the child process!\n");
        _exit(EXIT_SUCCESS);
    }
    else {
        int status;
        (void)waitpid(pid, &status, 0);
    }
    return EXIT_SUCCESS;
}

Далее следует разбор этой программы.

   pid_t pid = fork();

Первое заявление в главный вызывает Системный вызов fork для разделения выполнения на два процесса. Возвращаемое значение fork записывается в переменную типа pid_t — тип POSIX для идентификаторов процессов (PID).

    if (pid == -1) {
        perror("fork failed");
        exit(EXIT_FAILURE);
    }

Минус один указывает на ошибку в fork : новый процесс не был создан, поэтому выводится сообщение об ошибке.

Если форк прошел успешно, то теперь есть два процесса, оба выполняющие основная функция с той точки, где вилка вернулась. Чтобы процессы выполняли разные задачи, программа должна разветвляться по возвращаемому значению fork , чтобы определить, выполняется ли он как дочерний процесс или как родительский процесс.

   else if (pid == 0) {
      printf("Hello from the child process!\n");
      _exit(EXIT_SUCCESS);
   }

В дочернем процессе возвращаемое значение отображается как ноль (что является недопустимым идентификатором процесса). Дочерний процесс печатает желаемое приветственное сообщение, а затем завершает работу. (По техническим причинам POSIX Здесь необходимо использовать функцию _exit вместо стандарта C. выхода функция .)

   else {
      int status;
      (void)waitpid(pid, &status, 0);
   }

Другой процесс, родительский, получает от разветвить идентификатор дочернего процесса, который всегда является положительным числом. Родительский процесс передает этот идентификатор Системный вызов waitpid для приостановки выполнения до тех пор, пока дочерний элемент не выйдет. Когда это произошло, родительский элемент возобновляет выполнение и завершает работу с помощью метода заявление о возврате .

См. также

[ редактировать ]
  1. ^ Найман, Линус (25 августа 2016 г.). «Заметки по истории форка и объединения». IEEE Анналы истории вычислений . 38 (3): 84–87. дои : 10.1109/MAHC.2016.34 .
  2. ^ «s3.s из Research UNIX» . Гитхаб . 1970.
  3. ^ Кен Томпсон и Деннис Ричи (3 ноября 1971 г.). «SYS FORK (II)» (PDF) . Руководство программиста UNIX . Лаборатории Белла .
  4. ^ Ричи, Деннис М .; Томпсон, Кен (июль 1978 г.). «Система разделения времени UNIX» (PDF) . Белл Систем Тех. Дж . 57 (6). АТ&Т: 1905–1929. дои : 10.1002/j.1538-7305.1978.tb02136.x . Проверено 22 апреля 2014 г.
  5. ^ Перейти обратно: а б fork – Справочник по системным интерфейсам, Единая спецификация UNIX , версия 4 от Открытой группы.
  6. ^ pipe – Справочник по системным интерфейсам, Единая спецификация UNIX , версия 4 от Открытой группы.
  7. ^ Перейти обратно: а б vfork(2) Linux программиста Руководство – Системные вызовы
  8. ^ Перейти обратно: а б «Документация NetBSD: зачем реализовывать традиционный vfork()» . Проект NetBSD . Проверено 16 октября 2013 г.
  9. ^ "вфорк(2)". Руководство программиста UNIX, версия Virtual VAX-11 . Калифорнийский университет, Беркли. Декабрь 1979 года.
  10. ^ Перейти обратно: а б с vfork – Справочник по системным интерфейсам, Единая спецификация UNIX , версия 3 от Открытой группы.
  11. ^ Бах, Морис Дж. (1986). Проект операционной системы UNIX . Прентис-Холл. стр. 291–292. Бибкод : 1986duos.book.....B .
  12. ^ Перейти обратно: а б с Нахимовский, Грег (май 2006 г.). «Минимизация использования памяти для создания подпроцессов приложения» . Технологическая сеть Oracle . Корпорация Оракл . Архивировано из оригинала 22 сентября 2019 года.
  13. ^ Реализация OpenSolaris posix_spawn()
  14. ^ posix_spawn – Справочник по системным интерфейсам, Единая спецификация UNIX , версия 4 от Открытой группы.
  15. ^ fork(2) Plan 9 , том 1 Руководство программиста
  16. ^ intro(2) Plan 9 , том 1 Руководство программиста
  17. ^ rfork(2) FreeBSD по системным вызовам Руководство
  18. ^ Перейти обратно: а б Торвальдс, Линус (1999). «Грань Linux» . Открытые исходные коды: голоса революции открытого исходного кода . О'Рейли. ISBN  978-1-56592-582-3 .
  19. ^ «z/VM > z/VM 6.2.0 > Прикладное программирование > z/VM V6R2 OpenExtensions Документ соответствия POSIX > Документ соответствия POSIX.1 > Раздел 3. Примитивы процесса > 3.1 Создание и выполнение процесса > 3.1.1 Создание процесса» . ИБМ . Проверено 21 апреля 2015 г.
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 2f7717d95ecacec88e6a1c3897d3caa9__1717467840
URL1:https://arc.ask3.ru/arc/aa/2f/a9/2f7717d95ecacec88e6a1c3897d3caa9.html
Заголовок, (Title) документа по адресу, URL1:
fork (system call) - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)