Prosessi luodaan funktiolla pid_t *fork(void);
Funktio palauttaa kutsuvalle prosessille lapsiprosessin numeron ja lapsiprosessille 0.
fork()-kutsun tuloksena syntyy uusi prosessi, joka on 'klooni' äitiprosessista.
- yhteinen koodi
- samat muuttujien arvot
- samat prosessinkuvaajan perustiedot
- yhteiset avoimet tiedostot
Kummallakin on kuitenkin:
- oma data-alue
- oma prosessinkuvaaja
fork()-kutsun jälkeen ei voi olla varma siitä kumpi prosessi (äiti vai lapsi) jatkaa aiemmin suoritustaan. Jos järjestys tärkeää, on ohjelmoitava itse synkronointi
Esim 1.
int main(void) { int var; /* automatic variable on the stack */ pid_t pid; var = 88; if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1) perror("write error"); printf("before fork\n"); /* we don't flush stdout */ if ( (pid = fork()) < 0) perror("fork error"); else if (pid == 0) { /* child */ glob++; /* modify variables */ var++; } else sleep(2); /* parent */ printf("pid=%d,glob=%d,var=%d\n",getpid(), glob, var); exit(0); }
Lapsiprosessi luodaan, kun:
- halutaan suorittaa äiti- ja lapsiprosessissa erillinen osa samassa tiedostossa olevasta koodista. Esim. verkkosovelluksissa on tavallista, että palvelija luo lapsiprosessin antamaan palvelua ja jää itse odottamaan uusia palvelupyyntöjä.
- halutaan suorittaa kokonaan toinen ohjelma. Tällöin fork()-kutsun jälkeen on lapsiprosessissa myös exec()-kutsu, eli se vaihtaa suoritettavaa koodia. Esim. komentotulkit käyttävät tätä menetelmää.
Lapsi perii äidiltä kaikki avoimet tiedostokuvaajat. Sekä äiti että lapsi käyttävät yhteistä avoimet tiedostot taulun alkiota niillä on yhteinen luku / kirjoituspositio.