dalsi predchozi obsah
Dalsi: Rizeni procesu Predchozi: Systemove soubory

Prostredi procesu





Uvod

Pred popsanim nastroju pro rizeni procesu se musime nejdriv zabyvat prostredim, ve kterem procesy bezi. Dale se budeme zabyvat otazkou dodatecne spravy pameti.



Funkce main

Kazdy program v C musi nutne obsahovat funkci main. Jeji prototyp je:

int main (int argc, char *argv[]);

Kde argc je pocet argumentu na prikazove radce a argv je ukazatel na pole argumentu. Pri spusteni programu nejprve probehnou start-up funkce, ktere zajisti vyplneni techto struktur.



  Ukonceni procesu

je nekolik zakladnich cest, jak ukoncit proces:

  1. Normalni ukonceni
    1. return z funkce main
    2. volani exit
    3. volani _exit
  2. Abnormalni ukonceni
    1. volani abort
    2. ukonceni signalem


Funkce exit a _exit

Tyto dve funkce mohou primo ukoncit program. Funkce _exit primo vrati rizeni jadru a exit provede uklizeci procedury.

#include <stdlib.h>
void exit (int status);
#include <unistd.h>
void _exit (int status)

Klasicky priklad programu v C...

#include <stdio.h>

main()
{
printf("hello, world\n");
}
...je vlastne nespravny -- nema definovan navratovy kod.

Aby byl program uplny, meli bychom definovat navratovy kod takto:

     return(0);
nebo
     exit(0);

Pri definovani navratovych kodu si ale musime uvedomit, ze druhe reseni povede k vystraznemu hlaseni -- konflikt prototypu.



Funkce atexit

Pri pouziti ANSI C muzeme pouzit az 32 funkci, ktere se automaticky provedou pri volani exit. Tyto funkce (exit handlers) muzeme registrovat pomoci funkce atexit.

#include <stdlib.h>
int atexit (void (*func) (void));
Vraci: 0 kdyz OK, nenulova hodnota pri chybe

Pri volani exit norma ANSI zarucuje, krome jineho, uzavreni otevrenych souboru. Obrazek 5 ukazuje, jak program v C startuje a jakymi moznymi zpusoby lze ukoncit.

Zde ma byt moc hezky obrazek 'c_exit', skoda, ze ho nevidite

Obrazek 5: Jak program v C startuje a jak se ukoncuje

Priklad:

static void    my_exit1(void), my_exit2(void);
int
main(void)
{
    if (atexit(my_exit2) != 0)
        err_sys("can't register my_exit2");
    if (atexit(my_exit1) != 0)
        err_sys("can't register my_exit1");
    if (atexit(my_exit1) != 0)
        err_sys("can't register my_exit1");
    printf("main is done\n");
    return(0);
}
static void
my_exit1(void)
{
    printf("first exit handler\n");
}
static void
my_exit2(void)
{
    printf("second exit handler\n");
}



Argumenty prikazove radky

Kdyz je program provaden, funkce exec dovoluje predat programu prikazovou radku.

Priklad:

Normalne prikaz echo neprovadi echo cele radky. Po zkompilovani nasledujiciho programu ziskame echo prikazoveho radku.

int
main(int argc, char *argv[])
{
  int   i;

  for (i = 0; i < argc; i++)   /* echo all command-line args */
     printf("argv[%d]: %s\n", i, argv[i]);
  exit(0);
}

ANSI i POSIX.1 garantuji, ze argv[argc] je NULL pointer. To nam alternativne umozni psat:

      for (i=0; argv[i] != NULL; i++)



Rozdeleni pameti u programu v C

Historicky se program skladal z techto casti:

Text segment
Strojove instrukce provadene CPU. Casto je tento segment oznacen jako read-only -- ochrana proti nahodnemu prepisu
Segment inicializovanych dat
Casto se jmenuje jen data segment a obsahuje prirazene promenne. Napr. deklarace v C
      int maxcount = 99;
uvedena mimo jakoukoliv funkci, bude ulozena prave v teto oblasti.
Segment neinicializovanych dat
Tento segment se take nazyva bss (block started by symbol). Jadro vyplni tento segment pred spustenim nulami. Zde bude ulozeno napr. pole, deklarovane, mimo jakoukoli funkci, jako
      long count[1000];
Zasobnik
Zde budou ukladany lokalni promenne spolu s navratovymi adresami funkci.
Hromada
Dynamicke pridelovani pameti se casto odehrava v tomto segmentu. Historicky byla hromada (heap) umistena mezi konec neinicializovanych dat a zasobnik.

Viz tez obrazek 6.

Zde ma byt moc hezky obrazek 'memory', skoda, ze ho nevidite

Obrazek 6: Typicke usporadani pameti



Sdilene knihovny

Sdilene knihovny byly popsany jiz v prvnich implementacich Systemu V. Hlavni princip spociva v odstraneni knihoven z programu a spolecne sdileni jedine jejich kopie v pameti. Pri spusteni vice programu najednou se vyrazne usetri pamet. Nejjednodussi cestou, jak pouzit sdilenych knihoven, je spravne nastaveni parametru programu cc a ld. Po zkompilovani se sdilenymi knihovnami rapidne poklesne velikost vystupniho souboru (jednotlive casti programu zjistime prikazem size).



Sprava pameti

V ANSI C jsou definovany tri zakladni funkce pro dynamicke pridelovani pameti.

  1. malloc. Alokuje odpovidajici velikost pameti v bajtech. Hodnoty v alokovane pameti nejsou urceny.
  2. calloc. Alokuje pamet pro urceny pocet objektu specifikovane velikosti. Hodnoty pameti jsou nastaveny na 0.
  3. realloc. Meni velikost jiz jednou pridelene pameti. Pri zvetsovani rozsahu muze presunout celou oblast na nove misto.

#include <stdlib.h>
void *malloc (size_t size);
void *calloc (size_t nobj, size_t size);
void *realloc (void *ptr, size_t newsize);
Vsechny tri vraci: ukazatel kdyz OK, NULL pri chybe
void free(void *ptr);

Posledni je uvedena funkce free, ktera slouzi k uvolneni alokovaneho mista.



Promenne prostredi

Kazdemu programu je take predano prostredi (seznam promennych prostredi popisujici). Adresa pole urcujiciho prostredi je ulozena v globalni promenne environ.

      extern char **environ

Napr. prostredi, skladajici se ze ctyr retezcu, muze vypadat nasledovne. Viz obr. 7.

Zde ma byt moc hezky obrazek 'environm', skoda, ze ho nevidite

Obrazek 7: Prostredi sestavajici ze ctyr retezcu

Konvence pro prostredi vypada takto: name=value. Vetsina preddefinovanych jmen je psana velkymi pismeny, ale je to jen umluva.

Unixove jadro nikdy necte promenne -- jejich interpretace zalezi na jednotlivych aplikacich.

ANSI C definuje funkci, ktera slouzi ke zjisteni hodnoty promenne prostredi.

#include <stdlib.h>
char *getenv (const char *name);
Vraci: ukazatel na value patrici k name kdyz OK, NULL pri chybe

Obdobne funkce existuji i pro nastavovani promennych, ale ty nejsou prenositelne (putenv, setenv, unsetenv, claerenv).



Cviceni

  1. ??(nejaky uvod, zadani nejajeho programku...)

    Pokud to vas system umoznuje, zkompilujte tento program jednou staticky a jednou se sdilenymi knihovnami. Porovnejte veliskosti vyslednych souboru.


dalsi predchozi obsah
Dalsi: Rizeni procesu Predchozi: Systemove soubory

Ladislav Dobias
Sat Nov 1 15:38:32 MET 1997