GNU/Linux >> Znalost Linux >  >> Linux

UNIX / Linux Procesy:C fork() Funkce

Každá spuštěná instance programu je známá jako proces. Koncept procesů je pro operační systémy UNIX / Linux zásadní. Proces má svou vlastní identitu ve formě PID nebo ID procesu. Toto PID pro každý proces je jedinečné v celém operačním systému. Každý proces má také svůj vlastní adresní prostor procesu, kde jsou umístěny segmenty paměti, jako je segment kódu, datový segment, segment zásobníku atd. Pojem proces je velmi rozsáhlý a lze jej široce rozdělit na vytváření procesů, provádění procesů a ukončování procesů.

Linux Processes Series:část 1, část 2, část 3, část 4 (tento článek).

V tomto článku se zaměříme na aspekt tvorby procesu z hlediska programování. Zaměříme se na funkci fork() a pochopíme, jak funguje.

Funkce fork()

Funkce fork() se používá k vytvoření nového procesu duplikováním existujícího procesu, ze kterého je volán. Stávající proces, ze kterého je tato funkce volána, se stává rodičovským procesem a nově vytvořený proces se stává podřízeným procesem. Jak již bylo řečeno, dítě je duplicitní kopie rodiče, ale existují určité výjimky.

  • Dítě má jedinečné PID jako každý jiný proces spuštěný v operačním systému.
  • Podřízený má ID nadřazeného procesu, které je stejné jako PID procesu, který jej vytvořil.
  • Využití zdrojů a čítače času CPU jsou v podřízeném procesu vynulovány.
  • Sada nevyřízených signálů v dítěti je prázdná.
  • Dítěz nedědí žádné časovače od svého rodiče

Upozorňujeme, že výše uvedený seznam není vyčerpávající. V manuálové stránce fork() je zmíněno mnoho bodů. Důrazně bych doporučil čtenářům tohoto článku, aby si prošli tyto body v manuálové stránce funkce fork().

Typ návratu

Fork() má zajímavé chování při návratu k metodě volání. Pokud je funkce fork() úspěšná, vrátí se dvakrát. Jednou se vrátí v podřízeném procesu s návratovou hodnotou ‚0‘ a poté se vrátí v nadřazeném procesu s podřízeným PID jako návratovou hodnotou. Toto chování je způsobeno skutečností, že jakmile je zavolána větev, je vytvořen podřízený proces, a protože podřízený proces sdílí textový segment s nadřazeným procesem a pokračuje v provádění od dalšího příkazu ve stejném textovém segmentu, rozvětvení se vrátí dvakrát (jednou v nadřazeném a jednou za dítě).

Příklad vidlice C

Vezměme si příklad pro ilustraci použití funkce vidlice.

#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>

int var_glb; /* A global variable*/

int main(void)
{
    pid_t childPID;
    int var_lcl = 0;

    childPID = fork();

    if(childPID >= 0) // fork was successful
    {
        if(childPID == 0) // child process
        {
            var_lcl++;
            var_glb++;
            printf("\n Child Process :: var_lcl = [%d], var_glb[%d]\n", var_lcl, var_glb);
        }
        else //Parent process
        {
            var_lcl = 10;
            var_glb = 20;
            printf("\n Parent process :: var_lcl = [%d], var_glb[%d]\n", var_lcl, var_glb);
        }
    }
    else // fork failed
    {
        printf("\n Fork failed, quitting!!!!!!\n");
        return 1;
    }

    return 0;
}

Ve výše uvedeném kódu:

  • Místní a globální proměnná  (var_lcl a var_glb ) deklarovaná a inicializovaná hodnotou „0“
  • Následně se zavolá funkce fork() a její návratová hodnota se uloží do proměnné childPID.
  • Nyní je zkontrolována hodnota childPID, aby bylo zajištěno, že funkce fork() prošla.
  • Dále se na základě hodnoty childPID spustí kód pro rodiče a potomky.
  • Jedna věc, kterou je třeba poznamenat, je, proč se používají proměnné var_lcl a var_glb?
  • Používají se k tomu, aby ukázaly, že podřízený i nadřazený proces pracují na samostatných kopiích těchto proměnných.
  • K vyjádření výše uvedené skutečnosti se používají samostatné hodnoty těchto proměnných.
  • V linuxu se používá mechanismus kopírování při zápisu, kdy podřízený i rodič pracují na stejné kopii proměnné, dokud se jeden z nich nepokusí změnit její hodnotu.
  • Zda po rozvětvení poběží jako první dítě nebo rodič, závisí na plánovači.

Nyní, když je výše uvedený kód zkompilován a spuštěn:

$ ./fork

Parent process :: var_lcl = [10], var_glb[20]

Child Process :: var_lcl = [1], var_glb[1]

Vidíme, že ve výše uvedeném výstupu byly provedeny podřízený i nadřazený proces a protokoly ukazují samostatné hodnoty var_lcl a var_glb. Z toho vyplývá, že jak rodič, tak dítě měli svou vlastní kopii var_lcl a var_glb.

POZNÁMKA:Funkci getpid() lze použít k načtení ID procesu volajícího procesu a funkci getppid() lze použít k načtení PID nadřazeného procesu.


Linux
  1. Linux:Najděte a zabijte zombie procesy

  2. Jak najít všechny podřízené procesy?

  3. Opakování vidlice bash ssh Linuxu:žádné podřízené procesy

  1. 30 Cvičení procesů Linuxu pro systémové správce

  2. Linux – Init Process:Předchůdce všech procesů?

  3. UNIX / Linux:3 způsoby odesílání signálu do procesů

  1. Linuxové procesy – ID procesů, funkce fork, execv, wait, waitpid C

  2. Správa procesů v Ubuntu Linux

  3. Jak vypočítat využití CPU procesu a všech jeho podřízených procesů v Linuxu?