GNU/Linux >> Znalost Linux >  >> Linux

Jak funguje životní cyklus procesu Linux – nadřazený, podřízený a iniciační proces

Proces není nic jiného než běžící instance programu. Je také definován jako program v akci.

Koncept procesu je základním konceptem systému Linux. Procesy mohou plodit další procesy, zabíjet jiné procesy, komunikovat s jinými procesy a mnoho dalšího.

V tomto tutoriálu probereme životní cyklus procesu a dotykovou základnu na základě různých aspektů, kterými proces prochází ve svém životním cyklu.

1. Kód vs program vs proces

Nejprve pochopíme rozdíl mezi kódem, programem a procesem.

Kód: Následuje příklad kódu:

#include <stdio.h>
#include <unistd.h>

int main(void)
{
    printf("\n Hello World\n");
    sleep(10);

    return 0;
}

Uložme výše uvedenou část kódu do souboru s názvem helloWorld.c. Takže tento soubor se stane kódem.

Program: Nyní, když je kód zkompilován, vytvoří spustitelný soubor. Zde je návod, jak je výše uvedený kód zkompilován:

$ gcc -Wall helloWorld.c -o helloWorld

To by vytvořilo spustitelný soubor s názvem helloWorld. Tento spustitelný soubor je známý jako program.

Proces: Nyní spusťte tento spustitelný soubor:

$ ./helloWorld 

 Hello World

Po spuštění se vytvoří proces odpovídající tomuto spustitelnému souboru (nebo programu). Tento proces provede veškerý strojový kód, který byl v programu. To je důvod, proč je proces známý jako spuštěná instance programu.

Chcete-li zkontrolovat podrobnosti o nově vytvořeném procesu, spusťte příkaz ps následujícím způsobem:

$ ps -aef | grep hello*
1000      6163  3017  0 18:15 pts/0    00:00:00 ./helloWorld

Chcete-li porozumět výstupu příkazu ps, přečtěte si náš článek o příkladech příkazů ps.

2. Rodičovský a podřízený proces

Každý proces má nadřazený proces a může nebo nemusí mít podřízené procesy. Vezměme to jeden po druhém. Zvažte výstup příkazu ps na mém počítači Ubuntu:

1000      3008     1  0 12:50 ?        00:00:23 gnome-terminal
1000      3016  3008  0 12:50 ?        00:00:00 gnome-pty-helper
1000      3017  3008  0 12:50 pts/0    00:00:00 bash
1000      3079  3008  0 12:58 pts/1    00:00:00 bash
1000      3321     1  0 14:29 ?        00:00:12 gedit
root      5143     2  0 17:20 ?        00:00:04 [kworker/1:1]
root      5600     2  0 17:39 ?        00:00:00 [migration/1]
root      5642     2  0 17:39 ?        00:00:00 [kworker/u:69]
root      5643     2  0 17:39 ?        00:00:00 [kworker/u:70]
root      5677     2  0 17:39 ?        00:00:00 [kworker/0:2]
root      5680     2  0 17:39 ?        00:00:00 [hci0]
root      5956   916  0 17:39 ?        00:00:00 /sbin/dhclient -d -sf /usr/lib/NetworkManager/nm-dhcp-client.action -pf /run/sendsigs.
root      6181     2  0 18:35 ?        00:00:00 [kworker/1:0]
root      6190     2  0 18:40 ?        00:00:00 [kworker/1:2]
1000      6191  3079  0 18:43 pts/1    00:00:00 ps -aef

Celá čísla ve druhém a třetím sloupci výše uvedeného výstupu představují ID procesu a ID nadřazeného procesu. Sledujte čísla zvýrazněná tučně. Když jsem provedl příkaz 'ps -aef', byl vytvořen proces, jeho ID procesu je 6191. Nyní se podívejte na ID jeho nadřazeného procesu, je to 3079. Když se podíváte na začátek výstupu, uvidíte, že ID 3079 je ID procesu bash procesu. To potvrzuje, že bash shell je rodičem pro jakýkoli příkaz, který přes něj spustíte.

Podobně i pro procesy, které nejsou vytvořeny prostřednictvím shellu, existuje nějaký rodičovský proces. Stačí spustit příkaz „ps -aef“ na vašem počítači se systémem Linux a sledovat sloupec PPID (ID rodičovského procesu). Neuvidíte v něm žádnou prázdnou položku. To potvrzuje, že každý proces má nadřazený proces.

Nyní pojďme k dětským procesům. Kdykoli proces vytvoří další proces, první se nazývá rodič, zatímco druhý se nazývá podřízený proces. Technicky vzato je podřízený proces vytvořen voláním funkce fork() z kódu. Obvykle, když spustíte příkaz ze shellu, za fork() následuje řada funkcí exec().

Diskutovali jsme o tom, že každý proces má nadřazený proces, což může přinést otázku, co se stane s podřízeným procesem, jehož nadřazený proces je zabit? No, to je dobrá otázka, ale vraťme se k ní někdy později.

3. Proces init

Když se zavede systém Linux, první věc, která se nahraje do paměti, je vmlinuz. Je to spustitelný komprimovaný linuxový kernel. To má za následek vytvoření procesu init. Toto je první proces, který se vytvoří. Proces Init má PID jeden a je superrodičem všech procesů v linuxové relaci. Pokud považujete strukturu procesu Linux za strom, pak je init počátečním uzlem tohoto stromu.

Chcete-li potvrdit, že init je první proces, můžete na svém Linuxovém boxu spustit příkaz pstree. Tento příkaz zobrazí strom procesů pro relaci Linuxu.

Zde je ukázkový výstup:

init-+-NetworkManager-+-dhclient
     |                |-dnsmasq
     |                `-3*[{NetworkManager}]
     |-accounts-daemon---2*[{accounts-daemon}]
     |-acpid
     |-at-spi-bus-laun-+-dbus-daemon
     |                 `-3*[{at-spi-bus-laun}]
     |-at-spi2-registr---{at-spi2-registr}
     |-avahi-daemon---avahi-daemon
     |-bamfdaemon---3*[{bamfdaemon}]
     |-bluetoothd
     |-colord---{colord}
     |-console-kit-dae---64*[{console-kit-dae}]
     |-cron
     |-cups-browsed
     |-cupsd
     |-2*[dbus-daemon]
     |-dbus-launch
     |-dconf-service---2*[{dconf-service}]
     |-evince---3*[{evince}]
     |-evinced---{evinced}
     |-evolution-sourc---2*[{evolution-sourc}]
     |-firefox-+-plugin-containe---16*[{plugin-containe}]
     |         `-36*[{firefox}]
     |-gconfd-2
     |-gedit---3*[{gedit}]
     |-6*[getty]
     |-gnome-keyring-d---7*[{gnome-keyring-d}]
     |-gnome-terminal-+-bash
     |                |-bash-+-less
     |                |      `-pstree
     |                |-gnome-pty-helpe
     |                `-3*[{gnome-terminal}]
     |-gvfs-afc-volume---2*[{gvfs-afc-volume}]
     |-gvfs-gphoto2-vo---{gvfs-gphoto2-vo}
     |-gvfs-mtp-volume---{gvfs-mtp-volume}
     |-gvfs-udisks2-vo---{gvfs-udisks2-vo}
     |-gvfsd---{gvfsd}
     |-gvfsd-burn---2*[{gvfsd-burn}]
     |-gvfsd-fuse---4*[{gvfsd-fuse}]
     ...
     ...
     ...

Výstup potvrzuje, že init je v horní části stromu procesu. Také, pokud budete pozorovat text tučně, uvidíte úplný rodičovský potomek procesu pstree. Přečtěte si více o pstree v našem článku o stromech a pstree.

Nyní se vraťme k otázce (nechali jsme otevřenou v minulé sekci) o důsledcích, když je rodičovský proces zabit, když je dítě stále naživu. V tomto případě se dítě zjevně stane sirotkem, ale je adoptováno procesem init. Proces init se tedy stane novým rodičem těch podřízených procesů, jejichž rodiče jsou ukončeni.

4. Životní cyklus procesu

V této části probereme životní cyklus normálního linuxového procesu, než je zabit a odstraněn z tabulky procesů jádra.

  • Jak již bylo řečeno, pomocí fork() se vytvoří nový proces, a pokud má být spuštěn nový spustitelný soubor, potom se po fork() zavolá rodina funkcí exec(). Jakmile je tento nový proces vytvořen, zařadí se do fronty procesů, které jsou připraveny ke spuštění.
  • Pokud byla zavolána pouze fork(), je vysoce pravděpodobné, že nový proces běží v uživatelském režimu, ale pokud je zavolána exec(), bude nový proces běžet v režimu jádra, dokud pro něj nebude vytvořen nový adresní prostor procesu.
  • Pokud je proces spuštěn, proces s vyšší prioritou jej může předcházet přerušením. V tomto případě se preemptovaný proces znovu zařadí do fronty procesů, které jsou připraveny ke spuštění. Tento proces převezme plánovač v nějaké pozdější fázi.
  • Proces může během běhu vstoupit do režimu jádra. To je možné, když to vyžaduje přístup k nějakému zdroji, jako je textový soubor, který je uložen na pevném disku. Protože operace zahrnující přístup k hardwaru mohou nějakou dobu trvat, je vysoce pravděpodobné, že proces přejde do režimu spánku a probudí se pouze tehdy, když budou požadovaná data dostupná. Když je proces probuzen, neznamená to, že se začne okamžitě spouštět, znovu se zařadí do fronty a ve vhodnou dobu bude vybrán ke spuštění plánovačem.
  • Proces lze zabít mnoha způsoby. Může zavolat funkci exit() pro ukončení nebo může zpracovat signály Linuxu pro ukončení. Některé signály také nelze zachytit a způsobí okamžité ukončení procesu.
  • Existují různé typy procesů Linuxu. Jakmile je proces zabit, není zcela odstraněn. Záznam obsahující některé související informace je uchováván v tabulce adres procesu jádra, dokud nadřazený proces explicitně nezavolá funkce wait() nebo waitpid(), aby získal stav ukončení podřízeného procesu. Dokud to rodičovský proces neudělá, je ukončený proces známý jako zombie proces.

Linux
  1. Jak nainstalovat vtop na Linux

  2. Linux – proces „subreaper“?

  3. Jak zabít proces, jehož rodič je init?

  1. Jak spustit příkaz Linux na pozadí a odpojit proces v terminálu

  2. Jak nainstalovat a nakonfigurovat Monit na Linuxu pro monitorování procesů

  3. Jak získat podřízený proces z rodičovského procesu

  1. Jak zabít proces zombie na Linuxu

  2. Jak najít a zabít zombie proces v Linuxu

  3. Jak nechat podřízený proces zemřít po odchodu rodiče?