İşletim sistemi denildiği zaman windows, linux, ubuntu, pardus ve daha nice bilmediğimiz 100lercesini düşünebiliriz. Hepsinin sistem call dediğimiz öntanımlı fonksiyonları vardır. Bunlardan biri de fork'tur. İşletim sistemi çalıştığı zaman sürekli çalışan processler vardır. Sadece işletim sistemi değil bilgisayarımıza kurduğumuz programlar da processler ile çalışmaktadır. Ve her process kendine özgü alt processler oluşturur. Bu fork sayesinde mümkün olmaktadır. Kodun herhangi bir yerinde fork() komutu çalıştırdığımız zaman yeni bir process oluşmuş demektir.
fork() komutu çalıştırıldığı anda çocuk (child), ve onu oluşturan process ise veli (parent) adını almaktadır. Çocuk yaratıldığı anda velinin hangi değişkeni var ise onun hepsinin kopyasını alır. VE. bulunduğu konumdan itibaren çalışır.
Cümleler ile bu işi anlamak zor olabilir. En iyisi kodu incelerken cümlelerdekini düşünmek gerekir. Bunun için googleda fork yazdığınızda ilk bulacağınız koddan başlayalım.
#include <stdio.h>
#include <sys/types>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t pid;
pid = fork();
if(pid == 0)
{
printf("Ben cocugum, numaram \n");
sleep(1);
exit(0);
}
else
{
printf("Ben veliyim, numaram \n");
sleep(1); exit(0);
}
return 0;
}pid = fork() satırından sonra yeni cocuk oluşuyor ve pid değerine -1 veya 0 gelir. -1 gelmiş ise cocuk oluşturulamamıştır, 0 gelmiş ise sorun yoktur ve cocuk oluşmuştur. Demek ki output olarak "ben cocugum" ve "ben veliyim" yazıları gelecek. Ama sırası nedir. Kimse bilemez. Çünkü bilgisayarın çalışma mantıgında genellikle biraz o iş biraz öteki işi yapayım mantığı vardır. Bununla ilgili yazımı daha sonra yazarım.
Not: sleep(1) - 1 sn bekle, exit(0) bulunduğu procesi sonlandır.
Fork!u daha iyi anlamanın yolu dene yanıl yine dene mantığından geçtiğini düşündüğüm için bu koda biraz farklılıklar uygulayarak çalışma prensibini daha iyi kavrarız diye düşünüyorum. Gelin bir döngü kuralım,deneyelim.
int dongusayisi = 1;for(i = 0; i < dongusayisi; i++)
{
pid = fork();
if(pid == 0)
{
printf("%d Ben cocugum, numaram = %d %d\n",i,getpid(),getppid());
sleep(1);
}
else
{
printf("%d Ben veliyim, numaram = %d\n",i,getpid());
sleep(1);
}
}exit(0) (kodun üst ve alt taraflarını tekrar yapıştırmadım) dongusayisi = 1 iken ilk verdiğim koddan farkı olmayacaktır. dongusayisi = 2 yapin. ve çıkan sonucu inceleyin. Göreceksiniz ki cocuk bi anda veli olmuş:). Bu kısmı anlatmak zor, kodu takip edin. adım adım ise şöyle olur:
i = 0 iken - fork çalıştı (1.ci cocuk) -şimdi 1.ci cocuktaki i degeri i = 1. yani for(i = 1; i < 2; i++)
i = 0 iken - veli çalıştı
i = 1 iken - (1.ci cocuk) fork çalıştı (1.cocuğun cocugu) şimdi i = 2
i = 1 iken - (1.ci cocuk) veli çalıştı
i = 1 iken - veli çalıştı
bilgisayarın çalışma prensibine göre sonuçlar farklı sıralarda gelebilirler. not edelim: getpid() öntanımlı metodu bulunduğu procesin "process ID" sini verir. bu bir int değeridir. getppid() ise "parent process ID"dir. Yani velinin id'sidir.
Buradan görüldüğü gibi böyle birşey yapmak belki programcının işine yarayabilir ama genellikle başağrısıdır. Bir de şu şekilde denersek:
for(i = 0; i < dongusayisi; i++)
{
pid = fork();
if(pid == 0)
{
printf("%d Ben cocugum, numaram = %d %d\n",i,getpid(),getppid());
sleep(1); exit(0); // değişiklik burada!!!
}
else
{
printf("%d Ben veliyim, numaram = %d\n",i,getpid());
sleep(1);
}
}exit(0) Eğer çocuk procesi içinde exit(0) koyarsak 1 cocuk nested cocuklar üretmeden ömrünü tamamlayacaktır. Bu daha çok tercih edilebilir.
Peki fork yapmak ne işimize yarar, işkence gibi birşey? Mantık yürütmek gerekir ya da google'a bakmak.
Peki bu çoluk çocuk oluşturuldu kendi başlarına, ne olacak bunların sonu, birbirlerinden haberleri olacak mı? - tabi ki. çoluk cocuk veli kendi aralarında pipe (boru,hortum)vasıtasıyla işkence usulü anlaşırlar. Pipeler ile ilgili daha sonra yazacağım.
Kolay gelsin :)

0 yorum:
Yorum Gönder