Muokataan sivua Fork()

Siirry navigaatioon Siirry hakuun
Varoitus: Et ole kirjautunut sisään. IP-osoitteesi näkyy julkisesti kaikille, jos muokkaat. Jos kirjaudut sisään tai luot tunnuksen, muokkauksesi yhdistetään käyttäjänimeesi ja saat paremman käyttökokemuksen.

Kumoaminen voidaan suorittaa. Varmista alla olevasta vertailusta, että haluat saada aikaan tämän lopputuloksen, ja sen jälkeen julkaise alla näkyvät muutokset.

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. Funktion esittely löytyy unistd.h-otsikkotiedostosta.
 
==Prototyyppi==
pid_t fork()


==Määritelmä==
pid_t fork()
===Paluuarvo===
===Paluuarvo===
Palautusarvo (tyyppiä <tt>pid_t</tt>) on -1 virheen tapahtuessa, muuten se vastaa lapsiprosessin [[pid|prosessitunnusta]]. Lapsiprosessille palautusarvo näkyy nollana (0x0).
Palautusarvo (tyyppiä pid_t) on -1 virheen tapahtuessa, muuten se vastaa lapsiprosessin [[pid|prosessitunnusta]]. Lapsiprosessille palautusarvo näkyy nollana (0x0).


==Käyttö==
==Käyttö==
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").
=== Demostraatio ===
 
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]].
 
=== Esimerkki ===
Luodaan seuraavanlainen C-ohjelma:
Luodaan seuraavanlainen C-ohjelma:
<source lang="c">
<pre>
#include <stdio.h>
#include <stdio.h>
#include <unistd.h>
#include <unistd.h>
#include <sys/types.h>


int main() {
int main() {
        pid_t pid;
         printf("Luodaan taustaprosessi\n");
         printf("Luodaan taustaprosessi\n");
         pid = fork();
         pid_t pid = fork();
         if (pid==0)    /* Lapsiprosessille pid näkyy nollana */
         if (pid==0)    /* Lapsiprosessille pid näkyy nollana */
                 printf("Olen lapsiprosessi\n");
                 printf("Olen lapsiprosessi\n");
Rivi 31: Rivi 24:
         return 0;
         return 0;
}
}
</source>
</pre>
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:
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>
<pre>
Rivi 38: Rivi 31:
Terve Linux.fi
Terve Linux.fi
Olen isäntäprosessi
Olen isäntäprosessi
Terve Linux.fi
Linux.fi
</pre>
</pre>
Lisäämällä ehtolauseisiin yhden tulostusrivin sijaan vaikkapa silmukassa ajettavaa koodia (esim. <tt>while(1) printf("Lapsiprosessi");</tt>) huomataan, että prosesseja ajetaan vuorotellen.
Lisäämällä ehtolauseisiin yhden tulostusrivin sijaan vaikkapa silmukassa ajettavaa koodia (esim. <tt>while(1) printf("Lapsiprosessi");</tt>) huomataan, että prosesseja ajetaan vuorotellen.
Rivi 44: Rivi 37:
===[[demoni|Taustaprosessin]] luominen===
===[[demoni|Taustaprosessin]] luominen===
fork-funktion ajavan ohjelman toinen osa jää taustalle ja alkuperäinen ohjelma voidaan sammuttaa. Esimerkkikoodi:
fork-funktion ajavan ohjelman toinen osa jää taustalle ja alkuperäinen ohjelma voidaan sammuttaa. Esimerkkikoodi:
<source lang="c">
<pre>
#include <stdio.h>
#include <stdio.h>
#include <unistd.h>
#include <unistd.h>
#include <sys/types.h>


int main() {
int main() {
        pid_t pid;
         printf("Luodaan taustaprosessi\n");
         printf("Luodaan taustaprosessi\n");
         pid = fork();
         pid_t pid = fork();


         if (pid > 0) return 0;      /* Isäntäprosessi loppuu */
         if (pid > 0) return 0;      /* Isäntäprosessi loppuu */
Rivi 60: Rivi 51:
         return 0;
         return 0;
}
}
</source>
</pre>
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:
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
  $ ./taustaprosessi
Rivi 67: Rivi 58:
Ohjelma siis näyttää sammuvan heti tulostettuaan tekstirivin. Tutkitaanpa asiaa hieman tarkemmin. Aja komento
Ohjelma siis näyttää sammuvan heti tulostettuaan tekstirivin. Tutkitaanpa asiaa hieman tarkemmin. Aja komento
  [[ps]] aux | [[grep]] taustaprosessi
  [[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>.
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.




[[Luokka:Järjestelmä]]
[[Luokka:Järjestelmä]]
[[Luokka:Prosessienhallinta]]
Wikin materiaali on kaikkien vapaasti käytettävissä Creative Commons 3.0 - nimi mainittava -lisenssin alaisuudessa. TEKIJÄNOIKEUDEN ALAISEN MATERIAALIN KÄYTTÄMINEN ILMAN LUPAA ON EHDOTTOMASTI KIELLETTYÄ!

Muokataksesi tätä sivua vastaa alla olevaan kysymykseen (lisätietoja):

Peruuta Muokkausohjeet (avautuu uuteen ikkunaan)
Noudettu kohteesta ”https://www.linux.fi/wiki/Fork()