GNU/Linux >> Znalost Linux >  >> Linux

Naučte se a používejte systémová volání fork(), vfork(), wait() a exec() napříč systémy Linux

Zjistilo se, že v jakémkoli operačním systému založeném na Linuxu/Unixu je dobré rozumět fork a vfork systémová volání, jak se chovají, jak je můžeme používat a rozdíly mezi nimi. Spolu s těmito čekejte a exec systémová volání se používají pro vytváření procesů a různé další související úkoly.

Většina těchto pojmů je vysvětlena na příkladech programování. V tomto článku se budu zabývat tím, co jsou systémová volání fork, vfork, exec a wait, jejich rozlišovací znaky a jak je lze lépe používat.

fork()

fork(): Systémové volání k vytvoření podřízeného procesu.

[email protected] ~}$ man fork

Výsledkem bude výstup s uvedením toho, k čemu se fork používá, syntaxe a spolu se všemi požadovanými podrobnostmi.

Syntaxe použitá pro systémové volání fork je uvedena níže,

pid_t fork(void);

Systémové volání Fork vytvoří potomka, který se od svého nadřazeného procesu liší pouze v pid(ID procesu) appid(ID nadřazeného procesu) . Využití zdrojů je nastaveno na nulu. Zámky souborů a čekající signály se nedědí. (V Linuxu je „fork“ implementován jako „copy-on-write() “).

Poznámka:-Kopírovat při zápisu ” -> Kdykoli je zavoláno systémové volání fork(), vytvoří se kopie všech stránek (paměti) souvisejících s nadřazeným procesem a operačním systémem se načte do samostatného paměťového místa pro podřízený proces. To však není nutné ve všech případech a může být vyžadováno pouze tehdy, když nějaký proces zapisuje do tohoto adresního prostoru nebo oblasti paměti, pak se vytvoří/poskytne pouze samostatná kopie.

Vrácené hodnoty :-  PID (ID procesu) podřízeného procesu je vráceno v nadřazeném vláknu provádění a „nula “ se vrátí v podřízeném vláknu provádění. Následuje příklad c-programování, který vysvětluje, jak funguje systémová volání fork.

[e-mail chráněný] ~}$ vim 1_fork.c#include#includeInt main(void){printf("Before fork\n");fork();printf( "after fork\n");}[e-mail chráněný] ~}$ [e-mail chráněný] ~}$ cc 1_fork.c[e-mail protected] ~}$ ./a.outBefore forkAfter fork[e-mail chráněný] ~}$ 

Kdykoli dojde k nějakému systémovému volání, na jakémkoli unixovém/linuxovém stroji se odehrává spousta věcí.

Nejprve dojde k přepnutí kontextu z uživatelského režimu do režimu jádra (systému). To je založeno na prioritě procesu a operačním systému unix/linux, který používáme. Ve výše uvedeném příkladu kódu C používáme  „{“ otevírací složená závorka, která je vstupem do kontextu a „}“ uzavírající složená závorka je pro opuštění kontextu. Následující tabulka velmi jasně vysvětluje přepínání kontextu.

vfork()

vfork –> vytvořit podřízený proces a zablokovat nadřazený proces.

Poznámka:- Ve vforku jsou ovladače signálů zděděny, ale nejsou sdíleny.

[email protected] ~}$ man vfork

Výsledkem bude výstup s uvedením toho, k čemu se vfork používá, syntaxe a spolu se všemi požadovanými detaily.

pid_t vfork(void);

vfork je stejné jako fork s tím rozdílem, že chování není definováno, pokud proces vytvořený vfork buď modifikuje jakákoli data jiná než proměnná typu pid_t používaná k uložení návratové hodnoty p vfork, nebo volá jakoukoli jinou funkci mezi voláním _exit() nebo jedním z exec () rodina.

Poznámka: vfork je někdy označován jako speciální případ klonu.

Následuje příklad programování v C pro vfork(), jak to funguje.

[e-mail chráněný] ~}$ vim 1.vfork.c#include#includeInt main(void){printf("Před rozvětvením\n");vfork(); printf("after fork\n");}[e-mail chráněný] ~}$ vim 1.vfork.c[e-mail chráněný] ~}$ cc 1.vfork.c[e-mail chráněný] ~}$ ./a.outBefore vforkafter vforkafter vforka.out:cxa_atexit.c:100:__new_exitfn:Tvrzení `l !=NULL' selhalo. Přerušeno

Poznámka: – Jak bylo vysvětleno dříve, chování systémového volání vfork není mnohokrát předvídatelné. Stejně jako ve výše uvedeném případě se tisklo předtím jednou a potom dvakrát, ale přerušilo volání funkcí _exit(). Pokud to není jinak, je lepší používat systémové volání fork a co nejvíce se vyhnout používání vfork.

Rozdíly mezi fork() a vfork()

Vfork() chování je podrobněji vysvětleno v níže uvedeném programu.

[e-mail chráněný] ~}$ cat vfork_advanced.c#include #include #include int main(){    int n =10; pid_t pid =vfork(); //vytvoření podřízeného procesu    if (pid ==0)          //pokud se jedná o chilský proces    {        printf("Podřízený proces zahájen\n"); }    else//provádění nadřazeného procesu    {        printf("Nyní se vracím k nadřazenému procesu\n"); }    printf("hodnota n:%d \n",n); //ukázkový tisk pro kontrolu hodnoty „n“    return 0;}[email protected] ~}$ cc vfork_advanced.c[e-mail protected] ~}$ ./a.outChild process startvalue of n:10Nyní se vracím k nadřazené procesvalue z n:594325573a.out:cxa_atexit.c:100:__new_exitfn:Tvrzení `l !=NULL' selhalo. Přerušeno

Poznámka: Pokud opět pozorujete, výsledek vfork není definován. Hodnota „n“ byla poprvé vytištěna jako 10, což se očekává. Ale příště v nadřazeném procesu vytiskne nějakou hodnotu nesmyslu.

počkej()

Systémové volání wait() pozastaví provádění aktuálního procesu, dokud dítě neodejde nebo dokud nepřijde signál, jehož akcí je ukončit aktuální proces nebo obsluhu signálů volání.

pid_t wait(int * status);

Existují další systémová volání související s čekáním, jak je uvedeno níže,

1) waitpid() :pozastaví provádění aktuálního procesu, dokud dítě podle parametrů pid neukončí nebo dokud není doručen signál.

pid_t waitpid (pid_t pid, int *stav, možnosti int);

2) počkej3() :Pozastaví provádění aktuálního procesu, dokud dítě neukončí nebo dokud není doručen signál.

pid_t wait3(int *stav, možnosti int, struct rusage *rusage);

3) wait4() :Stejně jako wait3(), ale zahrnuje hodnotu pid_t pid.

pid_t wait3(pid_t pid, int *stav, možnosti int, struct rusage *rusage);

exec()

exec() rodina funkcí nebo volání sys nahradí aktuální obraz procesu novým obrazem procesu.

Existují funkce jako execl , execlp ,provedení ,execv , execvp a execvpe se používají ke spuštění souboru.

Tyto funkce jsou kombinacemi pole ukazatelů na null ukončené řetězce, které představují seznam argumentů, toto bude mít proměnnou cesty s některými kombinacemi proměnných prostředí.

exit()

Tato funkce se používá pro normální ukončení procesu. Stav procesu je zachycen pro budoucí použití. Existují další podobné funkce exit(3) a _exit(). , které se používají na základě ukončujícího procesu, který má člověk zájem použít nebo zachytit.

Závěr:-

Kombinace všech těchto systémových volání/funkcí se používají k vytváření, provádění a modifikaci procesů. Tyto funkce se také nazývají „skořápkové“ vytváření množin funkcí. Tyto funkce je třeba používat opatrně a mít na paměti výsledek a chování.


Linux
  1. Jak používat snímky LVM k obnově systémů Linux

  2. Jak používat příkazy strace a ltrace v Linuxu

  3. Jak nainstalovat a používat Glances k monitorování systémů Linux

  1. Jak nainstalovat a používat Git v systému Linux

  2. Jak nainstalovat a používat Telnet na systémech Linux

  3. Jak nainstalovat a používat TeamViewer v systému Linux [Kompletní průvodce]

  1. Jak nainstalovat a používat příkaz Ack v systému Linux

  2. Jak vygenerovat a používat klíč SSH v systému Linux?

  3. Jak nainstalovat a používat Nmap na Linux Mint 20