Як працюють виделка та виконати?


17

Я не маю великого досвіду, просто намагаюся долучитися до процесів, як вони інтерпретують обладнання на рівні користувача.

Отже, коли команда випускається з оболонки, fork()успадковує дочірній процес від неї та exec()завантажує дочірній процес у пам'ять та виконує.

  1. Якщо дочірній процес містить усі атрибути батьківського процесу (що є оригінальним процесом), то в чому ж полягає цей дочірні процес? Оригінальний процес також міг бути завантажений у пам'ять.
  2. Чи застосовується це forkта execконцепція до всієї виконуваної програми в UNIX? Як і для скрипта оболонки, або лише для команд? Чи застосовується це також для команд, вбудованих в оболонки?
  3. Коли використовується концепція копіювання при записі, якщо я виконую команду / сценарій?

Вибачте, що задаєте багато запитань одночасно, але всі ці запитання приходять мені в голову відразу, коли я думаю про будь-яке виконання команди.


Я не скажу, що це дублікат, але я думаю, що на деякі ваші запитання тут відповіли: unix.stackexchange.com/questions/136637/… та в іншій відповіді, пов’язаній у верхній частині цього.
золотинки

Відповіді:


22

Отже, коли команда запускається з оболонки, fork () успадковує дочірній процес її, а exec () завантажує дочірній процес у пам'ять і виконує.

Не зовсім. fork()клонує поточний процес, створюючи ідентичну дитину. exec()завантажує нову програму в поточний процес, замінюючи існуючу.

Мій Q:

Якщо дочірній процес містить усі атрибути батьківського процесу (який є оригінальним процесом), то в чому ж полягає цей дочірній процес? Оригінальний процес також міг бути завантажений у пам'ять.

Необхідність полягає в тому, що батьківський процес ще не хоче закінчуватися; він хоче, щоб новий процес вийшов з ладу і зробив щось одночасно, що він продовжує виконувати також.

Чи застосовується ця концепція fork та exec для всієї виконуваної програми в UNIX? Як і для сценарію оболонки, або лише для команд? Чи застосовується це також для команд, вбудованих в оболонки?

Для зовнішніх команд оболонка робить fork()так, що команда працює в новому процесі. Вбудовані просто управляються оболонкою безпосередньо. Ще одна помітна команда - це те exec, що повідомляє оболонку exec()зовнішній програмі без попереднього fork()ing. Це означає, що сама оболонка замінена новою програмою, і тому її вже немає, до якої програма повертається, коли вона закривається. Якщо ви скажете, exec trueтоді /bin/trueви заміните свою оболонку і негайно вийдете, не залишаючи більше нічого в своєму терміналі, тому він закриється.

коли використовується концепція копіювання при записі, якщо я виконую команду / сценарій?

Ще в кам'яну добу fork()насправді довелося копіювати всю пам'ять у процесі виклику на новий процес. Копіювати на запис - це оптимізація, коли таблиці сторінок налаштовані так, що два процеси починають спільний доступ до однієї і тієї ж пам’яті, а при необхідності копіюються лише ті сторінки, які записуються будь-яким процесом.


4
"Для майже кожної команди оболонка робить fork (), щоб команда виконувалась у новому процесі. Якщо ця команда є вбудованою, тоді дитині не потрібно виконувати окрему програму." Хороша відповідь, але цю частину слід відредагувати. Оболонка не роздрібнюється при запуску вбудованих. Він запускає ті, що безпосередньо в процесі активної оболонки. Це єдиний спосіб, як вбудовані люблять cdабо readмогли працювати. Відсутність розгортання також робить вбудовані файли набагато швидшими, ніж зовнішні команди.
Джон Кугельман підтримує Моніку

6
  1. Для деяких програм дочірній процес виконує одне (читати з послідовного порту, записувати в термінал), а батьківський процес продовжує робити щось інше (читати з терміналу, записувати в послідовний порт). Ще один класичний приклад - дочірній процес робить контрольну точку будь-якого тривалого обчислення. Переважно, дочірній процес виконує певні налаштування, як-от зміна каталогу, скидання обробників сигналів або скидання дескрипторів файлів, а потім закликає execve()накласти себе на інший код.
  2. fork()і exec()застосовуються до всіх виконуваних файлів - насправді поряд з argc та argv, і pipe, fork та exec - це те, що відрізняє Unix від інших операційних систем. Існує кілька спеціалізацій або узагальнень fork(), таких як BSD vfork(), План 9 rfork()та Linux ' clone(), але основна залишається тією ж.
  3. "копіювати при записі" насправді не з’являється користувачеві, це скоріше техніка оптимізації створення дочірнього процесу та під час його виконання. Стек викликів і купа (пам'ять, виділена з malloc()або навіть статичними або глобальними змінними області), можуть бути "копіювати при записі". Коли дочірній процес створюється за допомогоюfork()виклику, ядро ​​встановило б дочірній процес, щоб він мав такі самі сторінки пам'яті, як і heap та stack, як батьківський процес. Якщо апаратне забезпечення (блок управління пам’яттю) виявить запис купи або стека, ядро ​​отримає нову фізичну сторінку пам’яті, скопіює сторінку батьків на нову сторінку і відобразить цю нову сторінку в стеку або купі дочірнього процесу. Це являє собою оптимізацію, оскільки ядро ​​витрачає менше часу на налаштування відображень сторінок, ніж на повне копіювання стека та купи для дочірнього процесу.

Дякую Брюсу за вашу відповідь. Але так багато речей, які ви сказали тут, проходять через мою голову. Я не маю багато знань з цими речами. Я спробую налагодити роботу цих функцій, які ви згадали. Дуже дякую..!!
PriB

4
Якщо дочірній процес містить усі атрибути батьківського процесу (що є оригінальним процесом), то в чому ж полягає цей дочірні процес? Оригінальний процес також міг бути завантажений у пам'ять.

На це питання дуже наочно дано відповідь, поглянувши на найбільш ранні втілення Unix, які повинні були працювати в умовах жорстких обмежень пам'яті і мали лише один процес виконання в просторі пам'яті / адреси.

Багатозадачність було досягнуто шляхом заміни процесу на диск і заміни іншого процесу в.

Тепер forkсистемний виклик був майже таким самим: він замінив процес на диск, але замість того, щоб заміняти інший процес, він дав копії в пам'яті інший ідентифікатор процесу і повернувся до нього. І це був сприятливий момент, коли цей процес вирішив просто execперетворитись на інший виконуваний файл.

fork+ execтаким чином насправді не виникало помітних накладних витрат над нерестом: вам довелося все-таки поміняти процес на диск, і у будь-якому випадку у вас було старе зображення процесу в зручних місцях пам'яті.

Зі збільшенням кількості доступних блоків управління пам'яттю та пам’яттю та безлічі процесів в пам'яті спочатку незначна вартість вилки стала дещо більше неприємності для деяких архітектур: таким чином vforkнародилася.


2

Щоб зробити це максимально простим для розуміння, я скористаюся аналогією. Випікаємо пиріг!

Ми хапаємо книгу рецептів і починаємо читати і влаштовуємо на пиріг з полуниці з ревеню (мій улюблений), з ручної скоринкою. Майже все, що нам потрібно, - це на кухні, крім яєць та фруктів, але оскільки ми живемо на фермі, а фрукти в сезон, це не проблема. проблема в тому, що піч зламана і не вистачає часу, щоб зробити кожну справу. Не було б непогано мати більше одного зі мене?

fork () на допомогу. Зараз я двоє. і ми обидва прямуємо до кухні, щоб почати робити пиріг. ой. Тож ми дивимось на повернення з виделки. Я отримав велику кількість, він отримав нуль, тому я пряму на кухню, поки він прямує до курника та саду. Коли я проходжу повз духовку, я знову розщеплюю (), дивлюся на повернене значення: об’єм я отримав нуль. Він продовжує борошно, коли я дивлюся на розбиту піч. Я відкриваю двері, немає світла, я закриваю двері. Хтось знає, як зафіксувати духовку?

exec () на допомогу. Я дотягуюсь до вольтметра на моєму поясі інструменту, лампочка могла бути діагностичною, тому я перевіряю потужність, справді спрацьовує вимикач, легко виправити. Коли я підходжу до панелі вимикачів, я бачу товариша, що збирає ревінь. Гидота! Я вважаю за краще шоколадний шовковий пиріг.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.