Nykyinen versio |
Oma tekstisi |
Rivi 1: |
Rivi 1: |
| '''Fork()''' on SVr4, 4.3BSD ja POSIX.1-2001 -standardien mukainen funktio [[C]]-kielessä. Sillä luodaan ohjelmalle kutsun suorituskohtaan lapsiprosessi vastaavassa tilassa. Funktion esittely löytyy <tt>unistd.h</tt>-otsikkotiedostosta.
| | Fork on SVr4, 4.3BSD ja POSIX.1-2001 -standardienmukainen funktio [[C]]:ssä, jolla luodaan ohjelmalle kutsun suorituskohtaan lapsiprosessi vastaavassa tilassa. |
|
| |
|
| ==Prototyyppi== | | ==Määritelmä== |
| pid_t fork()
| | pid_t fork() |
| | | ===palautusarvo=== |
| ===Paluuarvo=== | | palautusarvo pid_t on -1 virheen tapauhtuessa, muuten se vastaa lapsiprosessin [[pid|prosessitunnusta]]. Lapsiprosessille palautusarvo näkyy nollana 0x0. |
| Palautusarvo (tyyppiä <tt>pid_t</tt>) on -1 virheen tapahtuessa, muuten se vastaa lapsiprosessin [[pid|prosessitunnusta]]. Lapsiprosessille palautusarvo näkyy nollana (0x0).
| | ==käyttö== |
| | | ===[[demoni|taustaprosessin]] luominen=== |
| ==Käyttö==
| | fork-funktion ajavan ohjelman toinen osa jää taustalle, alkuperäinen ohjelma voidaan sammuttaa esim [[exit()]]-kutsulla. |
| Fork on se tapa, jolla uusia prosesseja luodaan [[unix]]eissa. Jos lapsiprosessin pitää suorittaa toista ohjelmaa, se käyttää [[exec]]-kutsua forkin ja mahdollisten siivoustoimien jälkeen. Vaikka prosessin kopioiminen ennen kopion korvaamista toisella saattaa tuntua resurssien haaskaukselta, se ei sitä ole: lapsiprosessin muistiavaruus osoittaa samaa fyysistä muistia, kunnes lapsiprosessi kirjoittaa siihen, eikä käyttämätöntä muistia siis tarvitse kopioida ("Copy-on-Write").
| | pid_t prosessi = fork(); |
| | | if pid_t > exit(EXIT_SUCCESS); |
| Fork-kutsun lisäksi on olemassa [[clone]]-kutsu, jolla voi tarkemmin määritellä mitkä resurssit jäävät prosessien yhteisiksi. Tällä kutsulla luodaan [[säie|säikeet]].
| | if pid_t < exit(EXIT_FAILURE); |
| | | /*taustaprosessin toiminta*/ |
| === Esimerkki ===
| |
| Luodaan seuraavanlainen C-ohjelma:
| |
| <source lang="c">
| |
| #include <stdio.h>
| |
| #include <unistd.h>
| |
| #include <sys/types.h>
| |
| | |
| int main() {
| |
| pid_t pid;
| |
| printf("Luodaan taustaprosessi\n");
| |
| pid = fork();
| |
| if (pid==0) /* Lapsiprosessille pid näkyy nollana */
| |
| printf("Olen lapsiprosessi\n");
| |
| | |
| else if (pid>0) /* Forkkaus onnistui, tämä on isäntä */
| |
| printf("Olen isäntäprosessi\n");
| |
| printf("Terve Linux.fi\n");
| |
| return 0;
| |
| }
| |
| </source>
| |
| Tallennetaan koodi tiedostoon <tt>fork.c</tt> ja käännetään se komennolla <tt>[[gcc]] fork.c -o fork</tt>. Nyt ohjelman tuloste olisi seuraavanlainen:
| |
| <pre>
| |
| Luodaan taustaprosessi
| |
| Olen lapsiprosessi
| |
| Terve Linux.fi
| |
| Olen isäntäprosessi
| |
| Terve Linux.fi
| |
| </pre>
| |
| Lisäämällä ehtolauseisiin yhden tulostusrivin sijaan vaikkapa silmukassa ajettavaa koodia (esim. <tt>while(1) printf("Lapsiprosessi");</tt>) huomataan, että prosesseja ajetaan vuorotellen.
| |
| | |
| ===[[demoni|Taustaprosessin]] luominen=== | |
| fork-funktion ajavan ohjelman toinen osa jää taustalle ja alkuperäinen ohjelma voidaan sammuttaa. Esimerkkikoodi: | |
| <source lang="c">
| |
| #include <stdio.h>
| |
| #include <unistd.h>
| |
| #include <sys/types.h>
| |
| | |
| int main() {
| |
| pid_t pid;
| |
| printf("Luodaan taustaprosessi\n");
| |
| pid = fork();
| |
| | |
| if (pid > 0) return 0; /* Isäntäprosessi loppuu */
| |
| if (pid < 0) return -1; /* Forkkaus ei onnistunut 0_o */
| |
| | |
| while(1) { } /* Ikuinen silmukka */
| |
| return 0;
| |
| }
| |
| </source>
| |
| Tallennetaan koodi tiedostoon <tt>taustaprosessi.c</tt>, käännetään se komennolla <tt>gcc taustaprosessi.c -o taustaprosessi</tt> ja ajetaan se (<tt>./taustaprosessi</tt>). Tuloste on seuraavanlainen:
| |
| $ ./taustaprosessi
| |
| Luodaan taustaprosessi
| |
| $
| |
| Ohjelma siis näyttää sammuvan heti tulostettuaan tekstirivin. Tutkitaanpa asiaa hieman tarkemmin. Aja komento
| |
| [[ps]] aux | [[grep]] taustaprosessi
| |
| Jolloin huomaat, että taustaprosessi-niminen ohjelma on yhä ajossa. Myös [[top]]:in prosessilistauksessa sen pitäisi näkyä yläpäässä kuluttamassa paljon prosessoritehoa. Voit tappaa sen komennolla <tt>[[killall]] taustaprosessi</tt>.
| |
| | |
| | |
| [[Luokka:Järjestelmä]]
| |
| [[Luokka:Prosessienhallinta]]
| |