GNU/Linux >> Znalost Linux >  >> Linux

Rozdíl mezi fork(), vfork(), exec() a clone()

  1. fork() - vytvoří nový podřízený proces, který je úplnou kopií nadřazeného procesu. Podřízené a rodičovské procesy používají různé virtuální adresní prostory, které jsou zpočátku obsazeny stejnými paměťovými stránkami. Poté, jak jsou oba procesy vykonávány, se virtuální adresové prostory začínají stále více lišit, protože operační systém provádí líné kopírování paměťových stránek, které jsou zapisovány jedním z těchto dvou procesů, a přiřazuje nezávislé kopie upravených stránek paměti pro každý proces. Tato technika se nazývá Copy-On-Write (COW).
  2. vfork() - vytvoří nový podřízený proces, který je "rychlou" kopií nadřazeného procesu. Na rozdíl od systémového volání fork() , podřízené a rodičovské procesy sdílejí stejný virtuální adresní prostor. POZNÁMKA! Při použití stejného virtuálního adresového prostoru používá rodič i potomek stejný zásobník, ukazatel zásobníku a ukazatel instrukce, jako v případě klasického fork() ! Aby se zabránilo nechtěnému rušení mezi rodičem a potomkem, kteří používají stejný zásobník, provádění nadřazeného procesu je zmrazeno, dokud dítě nezavolá buď exec() (vytvořit nový virtuální adresní prostor a přechod do jiného zásobníku) nebo _exit() (ukončení provádění procesu). vfork() je optimalizace fork() pro model "fork-and-exec". Lze jej provést 4-5krát rychleji než fork() , protože na rozdíl od fork() (i s ohledem na COW), implementace vfork() systémové volání nezahrnuje vytvoření nového adresního prostoru (přidělení a nastavení nových adresářů stránek).
  3. clone() - vytvoří nový podřízený proces. Různé parametry tohoto systémového volání určují, které části nadřazeného procesu musí být zkopírovány do podřízeného procesu a které části mezi nimi budou sdíleny. Výsledkem je, že toto systémové volání lze použít k vytvoření všech druhů prováděcích entit, počínaje vlákny až po zcela nezávislé procesy. Ve skutečnosti clone() systémové volání je základem, který se používá pro implementaci pthread_create() a celá rodina fork() systémová volání.
  4. exec() - resetuje veškerou paměť procesu, načte a analyzuje specifikovaný spustitelný binární soubor, nastaví nový zásobník a předá řízení vstupnímu bodu načteného spustitelného souboru. Toto systémové volání nikdy nevrací řízení volajícímu a slouží k nahrání nového programu do již existujícího procesu. Toto systémové volání s fork() systémové volání dohromady tvoří klasický model řízení procesů UNIX s názvem „fork-and-exec“.

  • vfork() je zastaralá optimalizace. Před dobrou správou paměti fork() vytvořil úplnou kopii paměti rodiče, takže to bylo docela drahé. protože v mnoha případech fork() byl následován exec() , která současnou paměťovou mapu zahodí a vytvoří novou, to byly zbytečné výdaje. V současné době fork() nekopíruje paměť; je to jednoduše nastaveno jako "kopírovat při zápisu", takže fork() +exec() je stejně efektivní jako vfork() +exec() .

  • clone() je systémové volání používané fork() . s některými parametry vytvoří nový proces, s jinými vytvoří vlákno. rozdíl mezi nimi je pouze v tom, které datové struktury (paměťový prostor, stav procesoru, zásobník, PID, otevřené soubory atd.) jsou sdíleny nebo ne.


  • execve() nahradí aktuální spustitelný obraz jiným obrazem načteným ze spustitelného souboru.
  • fork() vytvoří podřízený proces.
  • vfork() je historicky optimalizovaná verze fork() , určené k použití, když execve() je voláno přímo po fork() . Ukázalo se, že funguje dobře v systémech bez MMU (kde fork() nemůže fungovat efektivně) a když fork() procesy s velkou pamětí pro spuštění nějakého malého programu (například Java Runtime.exec() ). POSIX standardizoval posix_spawn() nahradit tato poslední dvě modernější použití vfork() .
  • posix_spawn() dělá ekvivalent fork()/execve() , a také umožňuje nějaké fd žonglování mezi tím. Má nahradit fork()/execve() , hlavně pro platformy jiné než MMU.
  • pthread_create() vytvoří nové vlákno.
  • clone() je volání specifické pro Linux, které lze použít k implementaci čehokoli z fork() na pthread_create() . Poskytuje hodně kontroly. Inspirováno na rfork() .
  • rfork() je volání specifické pro plán 9. Má to být obecné volání, které umožňuje několik stupňů sdílení mezi úplnými procesy a vlákny.

Linux
  1. Rozdíl mezi [[ $a ==Z* ]] a [ $a ==Z* ]?

  2. Jaký je rozdíl mezi Sudo Su – a Sudo Su –?

  3. Rozdíl mezi Getty a Agetty?

  1. Rozdíl mezi Kill, Pkill a Killall?

  2. Rozdíl mezi „$ . Foo“ A „$ ./foo“??

  3. Rozdíl mezi ~/.profile a ~/.bash_profile?

  1. Rozdíl mezi Nss a Pam?

  2. Jaký je rozdíl mezi strtok_r a strtok_s v C?

  3. Jaký je rozdíl mezi ls a l?