Fork(), Exec(), Wait() Sistem Çağrıları

Slides:



Advertisements
Benzer bir sunumlar
Bölüm 11 Metin Dosyaları Metin Dosyaları Dosya Açma ve Kapama
Advertisements

Fonksiyonlar - Functions
Bölüm 12 ÜST DÜZEY KONULAR Dinamik Bellek Ayırma Önişlemci
Göstericiler (Pointers)
Nesneye Yönelik Programlama
void medyan(int cevap[]) { int j; siralama(cevap);
Bölüm 7 Fonksiyonlar GÖSTERGELER Gösterge Tanımı
Bölüm 2 C Dilinin Temelleri
Bölüm 4 İşlevlerve Modüler Programlama. 1 / 8 İşlev Tanımı /* İşlev açıklama satırı */ ( ) { }
Değişken Bildirimleri
Soru1: kuvvet(taban,us) Şeklinde bir yinelenen fonksiyon yazın
Elektrik-Elektronik Mühendisliği Bölümü
String Kütüphanesindeki Arama Fonksiyonları
Bölüm 2 C Dilinin Temelleri Genel Kavramlar
NESNEYE YÖNELİK PROGRAMLAMA
DOSYA İŞLEMLERİ.
Erişim Denetimi, Fonksiyon
Fonksiyonlar.
C++ Temelleri C++ genel amaçlı, nesne tabanlı, yüksek seviye programlama dilidir.
C ile Programlamaya Giriş
Paralel Programlamaya Giriş
FONKSİYONLAR.
DOSYA İŞLEMLERİ.
© Copyright 1992–2004 by Deitel & Associates, Inc. and Pearson Education Inc. All Rights Reserved. Fonksiyonlar –Programı modüler hale getirir –Yerel değişkenler,
Diziler Adres Kavramı Nesnelerin Adresleri sizeof Operatörü
Bilgisayar Programlama
Fscanf fonksiyonu fscanf () : Dosyadan bilgiyi okumak ve değişkenlere aktarmak için kullanılır. int fscanf(FILE *dosya, char* format, değişken adres listesi);
Fonksiyonlar Fonksiyon Tanımı Değer Döndürmeyen Fonksiyonlar
BPR152 ALGORİTMA VE PROGRAMLAMA - II Öğr. Gör. Bayram AKGÜL
Sistem Çağrıları Proses Kontrol Çağrıları Bellek Yönetim Çağrıları
SINIFLAR VE DİNAMİK BELLEK YÖNETİMİ VE SINIFLARIN DİĞER ÖZELLİKLERİ Yılmaz Kılıçaslan.
Bölüm 6 Fonksiyonlar Fonksiyon Tanımı Değer Döndürmeyen Fonksiyonlar
Paralel Programlamaya Giriş
Paralel Programlamaya Giriş 2
Paralel Programlamaya Giriş
The if statement. if Şartlı kontrol Koşul değimi doğru (1) yada yanlış (0) değeri üretir. Şartın doğru olması durumunda if satırından sonraki değimler.
PROGRAMLAMA DİLLERİNE GİRİŞ Ders 4: Fonksiyonlar
VERİ YAPILARI İşaretçi Nedir? Nesne Tabanlı Programlama.
1 Yapılandırılmamış programlama Prosedür/Fonksiyon gerekliliği Prosedural Programlama Fonksiyon Tanımlama/Prototip/Çağırma Örnek fonksiyonlar Fonksiyon.
SAÜ Bilgisayar Mühendisliği Dr. Cemil Öz
3. HAFTA 3. Hafta.
Fonksiyonlar.
BİLGİSAYAR programlama II
1 Değişken alanları Geçici değişkenler Birleşik ifadeler(bloklar) ve değişkenler Değişken Depolama Süresi ve Alanı –Local ve global değişkenler –Static.
Hafta2 Rekürsif Algoritmalar
Bilgisayar Görmesi Ders4:GUI OLUSTURMA Yrd. Doç. Dr. Serap KAZAN.
BİLGİSAYAR PROGRAMLAMA Ders 8: Fonksiyonlar Yrd. Doç. Dr. Altan MESUT Trakya Üniversitesi Bilgisayar Mühendisliği.
Bölüm 2 C Dilinin Temelleri Genel Kavramlar Yazım ve Noktalama Kuralları C Kütüphaneleri C Dilindeki Sözcükler Değer Sabitleri Veri Tipleri Değişkenler.
BİLGİSAYAR PROGRAMLAMA Ders 11: İşaretçi (Pointer) Kullanımı Yrd. Doç. Dr. Altan MESUT Trakya Üniversitesi Bilgisayar Mühendisliği.
Programlamaya Giriş-I Bölüm-1. Algoritma Algoritma günlük yaşamımızda yaptığımız işler sırasında sıklıkla kullandığımız bir yöntemdir. Algoritma, bir.
Bölüm 2 C Dilinin Temelleri
Fonksiyonlar ve Diziler
Bölüm 6 Fonksiyonlar Fonksiyon Tanımı Değer Döndürmeyen Fonksiyonlar
C Programlama Dili Bilgisayar Mühendisliği.
C’de Fonsiyonlar Aslı Ergün.
BİLGİSAYAR PROGRAMLAMA Ders 10: Dosyalama İşlemleri
Bölüm 7 Fonksiyonlar GÖSTERGELER Gösterge Tanımı
BİLGİSAYAR PROGRAMLAMA Ders 8: Fonksiyonlar
C Programlama Diline Giriş
BİLGİSAYAR PROGRAMLAMA Ders 11: İşaretçi (Pointer) Kullanımı
Bölüm 8 Diziler Dizi Tanımı Dizi Elemanlarına Değer Atama
Bölüm 2 C Dilinin Temelleri
Bölüm 8 Diziler Dizi Tanımı Dizi Elemanlarına Değer Atama
YAPISAL PROGRAMLAMA Hafta-6
YAPISAL PROGRAMLAMA Hafta-7
Bölüm 6: Kullanıcı Tanımlı Fonksiyonlar I
Bölüm 2 C Dilinin Temelleri
C ile Programlamaya Giriş
NİŞANTAŞI ÜNİVERSİTESİ
Diziler(Arrays).
Sunum transkripti:

Fork(), Exec(), Wait() Sistem Çağrıları İşletim Sistemleri Dersi

FORK() fork(), herhangi bir parametre almayan bir sistem çağrısıdır. Çağrıldığı andan itibaren işletim sistemi tarafından, ana processin bir kopyası oluşturulur. fork() çağrısını yapan process parent, ve bu çağrı ardından oluşan yeni process ise child olarak adlandırılır. fork() çağrısı yapıldığı andan itibaren, oluşan child process, parent’ın kaldığı yerden devam edecek şekilde bir kopya haline gelir.

FORK() fork() çalıştırıldığında aşağıdaki dönüş değerleri ortaya çıkmaktadır: fork() çağrısı başarısız olursa dönüş değeri -1 ’dir çağrı başarılı olursa; parent process için dönüş değeri, yeni oluşan child processin ID’si, child process için dönüş değeri 0 ’dır. fork() çağrısının dönüş değerleri konusunda şu yargıya varabiliriz: fork_donus_degeri > 0 : bu sonuç parent process içinde döndürülür fork_donus_degeri == 0 : bu sonuç child process içinde döndürülür fork_donus_degeri == -1 : çağrı başarısız oldu ve child oluşmadı. parent içinde döndürülür

FORK() Basit bir parent-child process aşağıdaki şekilde oluşturulabilir #include <stdio.h> #include <sys/types.h> #include <unistd.h> int main(void) { printf("Hello, World \n"); int fork_donus_degeri = fork(); printf("Bye Bye, World \n"); printf("fork donus degeri : %d", fork_donus_degeri); return 0; } Bu dönüş değerlerine göre parent ve child processlerimize farklı işlemler yaptırmamız mümkün olabilmektedir

#include <stdio. h> #include <sys/types #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <errno.h> int main(void) { int fork_donus_degeri = fork(); int sonuc; if (fork_donus_degeri == 0) { // burasi child processte calisir cunku == 0 degerini o saglayabilir sonuc = 0; int i; for(i=0;i<10;i++) { sleep(1); sonuc = sonuc + 1; printf("child_dongu_%d : sonuc : %d \n", i, sonuc); } printf("CHILD SONUCU : %d \n", sonuc); else if (fork_donus_degeri > 0) { // burasi parent processte calisir cunku > 0 degerini o saglayabilir sonuc = 1; sonuc = sonuc * 2; printf("parent_dongu_%d : sonuc : %d \n", i, sonuc); printf("PARENT SONUCU : %d \n", sonuc); else if (fork_donus_degeri == -1) { printf("ERROR : \n %d", errno); return 1; return 0;

SLEEP() Yukarıdaki örnek üzerinde yer alan sleep() komutu, parametre olarak verilen sayı boyunca saniye cinsinden processi uyku moduna alır. sleep(1); Bir process her zaman diğerinden önce sonlanabilir. Eğer bir process bittikten sonra ikincinin bitmesi için biraz süre varsa, bu durumda shell komut satırı sanki tüm program bitmiş gibi açılır. Ardından diğer process işlemini göstererek devam eder.

Yukarıdaki örneğin çıktısı aşağıdaki gibidir. Bir parent process’in, kendi child process’inden önce işleyişini tamamlaması ve kapanması istenmeyen bir durumdur. Bu nedele böyle durumlardan kaçınmak için parent tarafından kullanılabilecek bir wait(&donus_degeri) komutu vardır

Bir parent process’in, kendi child process’inden önce işleyişini tamamlaması ve kapanması istenmeyen bir durumdur. Bu nedenle böyle durumlardan kaçınmak için parent tarafından kullanılabilecek bir wait(&donus_degeri) komutu vardır

wait(&status) Üst proses bir alt prosesin sonlanmasını bekleyebilir. wait fonksiyonunun prototipi şöyledir: #include <sys/wait.h> wait(int *status); Fonksiyon parametre olarak sonlanan prosesin çıkış kodunun yerleştirileceği int türden nesnenin adresini alır.  wait fonksiyonu herhangi bir alt proses sonlanana kadar kendisini çağıran thread’i bloke etmektedir. Sonlanan prosesin id değeri, geri dönüş değeri olarak verilir. Ayrıca, parametre NULL adres olarak geçilebilir. Bu durumda fonksiyon  bize sonlanan prosesin çıkış kodunu vermez.

wait(&status) Aşağıda alt prosesin çıkış kodununun ekrana yazdırıldığı bir örnek görüyorsunuz: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> #include "general.h" int main(void) {     pid_t pidChild;     if ((pidChild = fork()) < 0)          err_sys("fork");     if (pidChild == 0) {            /* Alt proses */         sleep(5);         exit(100);     }     else {                          /* Ust proses */         int stat;         printf("Alt prosesin sonlanmasi bekleniyor...\n");         if (wait(&stat) < 0)              err_sys("wait");         printf("Alt prosesin sonlanma kodu: %d\n", WEXITSTATUS(stat));     }          return 0; }

EXEC() Çeşitli varyasyonları bulunan bu sistem çağrısı ile bir process içinde yeni bir program çağrısı yapılabilmektedir. (Çağrı yapılan, yeni bir process değil, yeni bir programdır.) #include <stdio.h> #include <sys/types.h> #include <unistd.h> int main(void) { int fork_donus_degeri = fork(); if (fork_donus_degeri == 0) { // burasi child processte calisir execl("/bin/ls", "/bin/ls","-la", NULL); } return 0;

EXEC() fork() ile oluşan yeni bir process, parent process ile aynıdır ve kod, stack ve kullanılan veriler child process içinde yer alır. exec*(..) ile bir child processin sahip olduğu kod, veri ve stack değiştirilebilir. Bunun anlamı, child process parent’ın bir kopyası olarak doğmuştur ancak artık başka bir işlem yürütmektedir ve exec*(..) bitene kadar child beklemededir.

EXEC() fork işlemi sonrasında alt ve üst prosesler aynı program kodunu çalıştırıyor durumda olurlar. Halbuki pek çok uygulamada programcı yaratmış olduğu alt prosesin farklı bir program kodunu çalıştırmasını ister. İşte exec fonksiyonları prosesin başka bir program olarak çalışmaya devam etmesini sağlamaktadır.  exec işlemleri sonrasında prosesin id değeri ve kontrol bloğu değişmez. Prosesin kod, data ve bash alanları çalıştırılabilen (executable) dosyadan alınarak yüklenir. Proses artık yaşamını başka bir program olarak sürdürür.  Tüm exec fonksiyonlarının prototipleri <unistd.h> dosyası içersindedir.

EXEC() Exec komutu aldığı parametrelere ve gördüğü işlevlere göre 6 farklı şekilde çalışırlar. Bunlar ve aldıkları parametreler aşağıdaki gibidir. int execl(const char *path, const char *arg0, … /*,(char *) 0 */); int execv(const char *path, char *const argv[]); int execle(const char *path, const char *arg0, … /*, (char *) 0, char *const envp[] */); int execve(const char *path, char *const argv[], char *const envp[]); int execlp(const char * file, const char *arg0, … /*, (char *) 0 */); int execvp(const char *file, char *const argv[]);

EXEC() exec fonksiyonlarının l’li (execl, execle, execlp) ve v’li (execv, execve, execvp) biçimleri vardır. Bunların l’li biçimleri komut satırı argümanlarını bir liste olarak, v’li biçimleri ise bir dizi olarak alırlar. Ayrıca bazı exec fonksiyon isimlerinin ‘e’ ya da ‘p’ harfiyle sonlandırıldığını göreceksiniz. Fonksiyonların e’li biçimleri çevre değişkenlerini (environment variables) de programcıdan istemektedir. p’li biçimler çalıştırılabilen dosyanın yerinin belirlenmesinde PATH çevre değişkenlerini dikkate alırlar.

fork() ve exec*() işlemlerinin yürümesi yandaki şekilde ifade edildiği gibidir.

Getpid() Mevcut process için process_ID’yi döndürür. Örnek bir kod aşağıdaki şekildedir. #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <sys/wait.h> int main(void) { int pid; pid = getpid(); printf("ilk alınan pid : %d\n", pid); int fork_donus_degeri = fork(); if (fork_donus_degeri == 0) { // burasi child processte calisir printf("CHILD pid : %d\n", pid); } else if (fork_donus_degeri > 0) { // burasi parent processte calisir pid = getppid(); printf("PARENT pid : %d\n", pid); else if (fork_donus_degeri == -1) { printf("ERROR : \n"); return 1; pid = getpid(); printf("son alinan pid : %d\n", pid); return 0;

getppid() , getpgrp() getppid(), mevcut bir child process’in parent process ID’sini döndürür. getpgrp(), bir process grubunun (parent ve child içeren) grup ID’sini döndürür. Bir grubun grup ID’si, o child processleri oluşturan parent process’in ID’sidir.

Örnekler fork.c #include <stdio.h> #include <sys/types.h> #include <unistd.h> int main(){ pid_t cocuk_pid; printf(“Ana sürecin pid = %d\n”, (int)getpid() ); cocuk_pid=fork(); if (cocuk_pid!=0){ printf(“burası ana sürectir, süreç id pid=%d\n”,(int)getpid()); printf(“çocuk sürecin idsi pid = %d\n”,(int)cocuk_pid); } else{ printf(“burası çocuk süreçtir, pid=%d\n”, (int)getpid()); } return 0; }

Waitpid() #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> void err_sys(const char *msg) {     perror(msg);     fflush(stdout);     exit(EXIT_FAILURE); } int main(void) {     pid_t pidChild;     if ((pidChild = fork()) < 0)          err_sys("fork");     if (pidChild == 0) {              /* Alt proses */         sleep(5);         exit(100);     }     else {                            /* Ust proses */         int stat;         printf("Alt prosesin sonlanmasi bekleniyor...\n");         if (waitpid(pidChild, &stat, 0) < 0)              err_sys("waitpid");            }          return 0; }