Hlavní navigace

Programování pod Linuxem pro všechny (8)

Jakub Matys

V dnešním dílu se podíváme na vytváření procesů. Proberu zde funkci fork() a funkce ze skupiny exec. Máte se tedy na co těšit...

Vytváření procesů

Pro snadné vytvoření procesu (přesněji spuštění programu) z programu je možné použít funkci system(). Použití této funkce se ale obecně nedoporučuje, protože nejdříve vytvoří subproces, ve kterém běží bash (/bin/sh), který pak zadaný příkaz spustí. To s sebou nese bezpečnostní rizika – spuštěný program podléhá všem vlastnostem, omezením a bezpečnostním opatřením platným pro systémový příkazový procesor.

Vytvoření podřízeného procesu funkcí fork()

Pomocí funkce fork() se vytvoří duplicitní kopie aktuálního procesu, která se nazývá podřízený proces. Nadřízený proces pokračuje ve své existenci a v realizaci svého kódu následujícího po volání funkce fork(). Podřízený proces realizuje stejný program od stejného místa. Funkce fork() vrací jiný návratový kód nadřízenému procesu a jiný podřízenému procesu. Návratovou hodnotou v nadřízeném procesu je identifikační číslo podřízeného procesu, návratovou hodnotou v podřízeném procesu je nula. Díky tomuto faktu je možné odlišit nadřízený proces od podřízeného při psaní kódu.

Program v příkladu vytvoří duplikát procesu. První blok v příkazu if se provede pouze v nadřízeném procesu, zatímco blok po kauzuli else se provede pouze v podřízeném procesu.

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
  pid_t child_pid;

  printf("ID procesu je %d\n", (int) getpid());

  child_pid = fork();
  if (child_pid != 0) {
    printf("Toto je rodicovsky proces, s ID %d\n", (int) getpid());
    printf("ID podrizeneho procesu je %d\n", (int) child_pid);
  }
  else
    printf("Toto je podrizeny proces s ID %d\n", (int) getpid());

  return(0);
} 

Spouštění programů pomocí funkcí skupiny exec

Funkce exec nahradí program běžící v podřízeném procesu jiným progarmem. Při volání funkce exec proces ukončí provádění aktuálního programu a zahájí realizaci specifikovaného programu od začátku (pokud nenastala chyba).

Ve skupině funkcí exec je několik funkcí, které se mírně liší způsobem volání a výsledkem své činnosti:

  • Pokud funkce ve svém označení obsahují písmeno p (execvp, execlp), přijímají jako argument jmého programu a hledají uvedený program v aktuálním seznamu adresářů uvedeném v proměnné PATH. Pokud jméno funkce neobsahuje písmeno p, musí se uvést jméno spouštěného programu včetně úplné cesty.
  • Funkce s písmenem v (execv, execvp a execve) přijímají seznam argumentů (nulou ukončené pole ukazatelů na znakové řetězce), které mají předat spouštěnému prograu.
  • Funkce obsahující ve svém označení písmeno e (execve a execle) akceptují další argument, pole systémových proměnných. Tímto argumentem je nulou ukončené pole ukazatelů na znakové řetězce. Každý řetězec musí být ve tvaru „PROMENNA=hodnota“.

Seznam argumentů předávaný novému programu pracuje na stejném principu jako seznam argumentů předávaný funkci main(). Nesmíte zapomenout, že první argument musí obsahovat jméno programu (stejně jako argv[0]).

Spuštění programu pomocí funkcí fork() a exec

Při spouštění podprogramu uvnitř jiného programu nejdříve volejte funkci fork() a teprve pak funkce ze skupiny exec. Tímto docílíte toho, že volající kód v nadřízeném procesu může pokračovat ve své realizaci, zatímo v podřízeném procesu je volající program nahrazen novým programem.

Program v příkladu zobrazuje seznam souborů v hlavním adresáři pomocí příkazu ls -l /:

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

/* Funkce vytvori podrizeny proces a spusti v nem novy
program. PROGRAM je jmeno programu, ktery se ma spustit.
ARG_LIST je seznam argumentu programu. Vraci ID
vytvoreneho procesu. */

int spawn(char *program, char **arg_list)
{
  pid_t child_pid;

  /* Vytvoreni noveho procesu */
  child_pid = fork();
  if (child_pid != 0)
    /* Toto je rodicovsky proces */
    return(child_pid);
  else {
    /* Nyni se spusti PROGRAM */
    execvp(program, arg_list);
    /* Toto funkce vraci pouze pokud nastala chyba */
    fprintf(stderr, "Chyba pri volani funkce execvp()\n");
    abort();
  }
}

int main()
{
  /* Pole argumentu predavanych pri volani prikazu ls */
  char *arg_list[] = {
    "ls",
    "-l",
    "/",
    NULL
  };

  /* Volani funkce spawn */
  printf("PID spousteneho procesu je %d\n", (int) spawn("ls", arg_list));

  return(0);
} 

To by bylo pro dnešek vše, v příštím dílu se podíváme na plánování procesů pomocí funkce nice() a na zpracování signálů.

Našli jste v článku chybu?

23. 4. 2004 19:00

Taif (neregistrovaný)

Cuz,
syscall fork(), zduplicitni dany proces (viz. novy task_struct atd...) ... nemusis se bat o dynamickou pamet ci o otevrene soubory -> nebudou se ovlivnovat (resp. read-on-write metoda => zduplicidni se po prvnim pouziti jednim z techto dvou), takze se prakticky o nic starat nemusis. [jine je to s VLAKNAMA!!!]. Co se tyce exec, tak je to jednoduche ... stary program v pameti je nahrazen novym (+ ošetření).


23. 4. 2004 9:13

Dan (neregistrovaný)

Ahoj,
prispivam uz trosku pozde, ale zrovna ted je to pro me aktualni. Protoze je to clanek pro zacatecniky, a fork() a exec() jsem jeste nikdy nepouzil, chci se zeptat na par drobnosti:

Jak je to s uvolnovanim zdroju? Co kdyz ma rodicovsky proces dynamicky alokovanou nejakou pamet, otevrene soubory ci zarizeni, namapovane soubory nebo jine veci. Je treba, aby toto vsechno potomek uvolnoval/uzaviral? Na co si dat pozor mezi spustenim fork() a exec()? Existuje nejaky soubor pravidel, co udela…


Vitalia.cz: To nejhorší při horečce u dětí: Febrilní křeče

To nejhorší při horečce u dětí: Febrilní křeče

DigiZone.cz: R2B2 a Hybrid uzavřely partnerství

R2B2 a Hybrid uzavřely partnerství

Vitalia.cz: 7 originálních adventních kalendářů pro mlsné

7 originálních adventních kalendářů pro mlsné

120na80.cz: Boreliózu nelze žádným testem prokázat

Boreliózu nelze žádným testem prokázat

Měšec.cz: Za palivo zaplatíte mobilem (TEST)

Za palivo zaplatíte mobilem (TEST)

Lupa.cz: Propustili je z Avastu, už po nich sahá ESET

Propustili je z Avastu, už po nich sahá ESET

Vitalia.cz: Jak vybrat ořechy do cukroví a kde mají levné

Jak vybrat ořechy do cukroví a kde mají levné

Vitalia.cz: Pamlsková vyhláška bude platit jen na základkách

Pamlsková vyhláška bude platit jen na základkách

Vitalia.cz: Test na HIV je zdarma i za pět set

Test na HIV je zdarma i za pět set

Lupa.cz: Insolvenční řízení kvůli cookies? Vítejte v ČR

Insolvenční řízení kvůli cookies? Vítejte v ČR

Měšec.cz: U levneELEKTRO.cz už reklamaci nevyřídíte

U levneELEKTRO.cz už reklamaci nevyřídíte

120na80.cz: 5 nejčastějších mýtů o kondomech

5 nejčastějších mýtů o kondomech

Vitalia.cz: Nejlepší obranou při nachlazení je útok

Nejlepší obranou při nachlazení je útok

Podnikatel.cz: Vládu obejde, kvůli EET rovnou do sněmovny

Vládu obejde, kvůli EET rovnou do sněmovny

Vitalia.cz: Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Podnikatel.cz: Podnikatelům dorazí varování od BSA

Podnikatelům dorazí varování od BSA

DigiZone.cz: Ohrozí Freedom TV přechodové sítě?

Ohrozí Freedom TV přechodové sítě?

Měšec.cz: Jak vymáhat výživné zadarmo?

Jak vymáhat výživné zadarmo?

120na80.cz: Pánové, pečujte o svoje přirození a prostatu

Pánové, pečujte o svoje přirození a prostatu

Podnikatel.cz: Chaos u EET pokračuje. Jsou tu další návrhy

Chaos u EET pokračuje. Jsou tu další návrhy