İşletim Sistemleri. Dr. Binnur Kurt binnur.kurt@gmail.com. Omega Eğitim ve Danışmanlık http://www.omegaegitim.com. İşletim Sistemleri



Benzer belgeler
İşletim Sistemleri. Dr. Binnur Kurt Omega Eğitim ve Danışmanlık İşletim Sistemleri

Proses. Prosesler 2. İşletim Sistemleri

PROSESLER. Proses. Proses

Bilgisayar İşletim Sistemleri BLG 312

Giriş. geleneksel işletim sistemlerinde her prosesin. aynı adres uzayında birden fazla akış kontrolü gerekebilir

Bilgisayar İşletim Sistemleri BLG 312

Giriş. İplik Modeli. geleneksel işletim sistemlerinde her prosesin özel adres uzayı ve tek akış kontrolü var.

İşletim Sistemleri. İşletim Sistemleri. Dr. Binnur Kurt Omega Eğitim ve Danışmanlık

YZM 3102 İşletim Sistemleri

Multicore/Multithread Programlama

İşletim Sistemlerine Giriş

İŞLETİM SİSTEMLERİ. (Operating Systems)

Yrd. Doç. Dr. Caner ÖZCAN

İŞ SIRALAMA. İş Sıralamanın Amaçları. İş Sıralama Türleri - 1. İş Sıralama. İş Sıralama Türleri - 2

Yrd. Doç. Dr. Caner ÖZCAN

İşletim Sistemleri (Operating Systems)

İşletim Sistemleri. Dr. Binnur Kurt Omega Eğitim ve Danışmanlık İşletim Sistemleri

İŞ SIRALAMA. İş Sıralama 6. İşletim Sistemleri

NESNEYE YÖNELİK PROGRAMLAMA

Yrd. Doç. Dr. A. Burak İNNER

BLM 112- Programlama Dilleri II. Hafta 5 İşaretçiler (Pointers)

BLM-112 PROGRAMLAMA DİLLERİ II. Ders-3 İşaretçiler (Pointer) (Kısım-2)

Öğr. Gör. Serkan AKSU 1

PROGRAMLAMAYA GİRİŞ FONKSİYONLAR

ELN1001 BİLGİSAYAR PROGRAMLAMA I

Linux'ta Kabuk ve Kabuk Programlama

Pointer Kavramı. Veri Yapıları

Bölüm 3: İşlemler Operating System Concepts with Java 8th Edition 3.1 Silberschatz, Galvin and Gagne 2009

Bölüm 3: İşlemler Operating System Concepts with Java 8th Edition 3.1 Silberschatz, Galvin and Gagne 2009

Prosesler Arası Haberleşme ve Senkronizasyon

PROGRAMLAMAYA GİRİŞ DERS 2

Binnur Kurt İstanbul Teknik Üniversitesi Bilgisayar MühendisliM

ELN1002 BİLGİSAYAR PROGRAMLAMA 2

İŞLETİM SİSTEMLERİ (POSIX THREADS v1)

Temel Bilgisayar Programlama Final Sınavı Çalışma Notları

if (ad == "Sabri") Console.WriteLine("Merhaba Sabri. Ne zamandır gözükmüyodun...");

İşletim Sistemlerinde Çok Prosesli Çalışma

BİLGİ İŞLEM DERS 1. Yrd Doç Dr. Ferhat ÖZOK MSGSU FİZİK BÖLÜMÜ MSGSU FİZİK BÖLÜMÜ

İşletim Sistemlerine Giriş

İŞLETİM SİSTEMLERİ DÖNEMİÇİ SINAVI

İşletim Sistemleri. Dr. Binnur Kurt Omega Eğitim ve Danışmanlık İşletim Sistemleri

BLM 112- Programlama Dilleri II. Hafta 2 C Programlarının Bellek Düzeni ve Rekürsif (Özyinelemeli) Fonksiyonlar

ALGORİTMA VE PROGRAMLAMA I

Veritabanı. Ders 2 VERİTABANI

ALGORİTMA VE PROGRAMLAMA I

Program Nedir? Program, bir problemin çözümü için herhangi bir programlama dilinin kuralları ile oluşturulmuş komut kümesidir.

Uzaktan Eğitim Uygulama ve Araştırma Merkezi

BLM-111 PROGRAMLAMA DİLLERİ I. Ders-12 Fonksiyonlar. Yrd. Doç. Dr. Ümit ATİLA

Bil101 Bilgisayar Yazılımı I. M. Erdem ÇORAPÇIOĞLU Bilgisayar Yüksek Mühendisi

MPLAB IDE v7.60 PROGRAMI KULLANIMI

Özyineleme (Recursion)

Temel Giriş/Çıkış Fonksiyonları

C++ Dersi: Nesne Tabanlı Programlama

İNTERNET PROGRAMCILIĞI - II

Bilgisayar Sistemlerine Genel Bakış

Fonksiyonlar. C++ ve NESNEYE DAYALI PROGRAMLAMA 51. /* Fonksiyon: kup Bir tamsayının küpünü hesaplar */ long int kup(int x) {

REALTIME LINUX. 3. Linux ve Özgür Yazılım Şenliği Murat Demirten, 16 Mayıs 2004, Ankara

Pascalda oluşturulacak dosyalar değişkenler gibi programın başında tanımlanır.

Windows'da çalışırken pek çok durumda bir işe başlamadan önce işletim sisteminin o işe ilişkin bilgileri depolayacağı bir alan yaratması gerekir.

Hafta 13 Fonksiyonlar

C PROGRAMLAMA D İ L İ

BİLGİ İŞLEM DERS 3. Yrd Doç Dr. Ferhat ÖZOK MSGSU FİZİK BÖLÜMÜ MSGSU FİZİK BÖLÜMÜ

BLGM 343 DENEY 8 * TCP İLE VERİ İLETİŞİMİ

Bilgi ve İletişim Teknolojileri (JFM 102) Ders 7. LINUX OS (Sistem Yapısı) BİLGİ & İLETİŞİM TEKNOLOJİLERİ. LINUX Yapısı

Bölüm 4: Threads (İş Parçaları)

Üst Düzey Programlama

Yrd. Doç. Dr. A. Burak İNNER

ELN1002 BİLGİSAYAR PROGRAMLAMA 2

BİL-142 Bilgisayar Programlama II

Veritabanı Uygulamaları Tasarımı

Linux Assembly Programlamaya Giriş

sayi=3 harf=a reelsayi=8.72 Bellek durumu 5. İşaretç iler (pointers)

Telefon Rehberi Uygulaması

BTEP243 Ders 3. class Yazım Kuralı:

İŞLETİM SİSTEMİ KATMANLARI (Çekirdek, kabuk ve diğer temel kavramlar) Bir işletim sisteminin yazılım tasarımında ele alınması gereken iki önemli konu

Internet Programming II

DERS 3 MİKROİŞLEMCİ SİSTEM MİMARİSİ. İçerik

Bilgisayar İşletim Sistemleri BLG 312

Sınav tarihi : Süre : 60 dak. a) strstr b) strchr c) strcat d) strcpy e) strlen. a) b) d) e) 0

Bölüm 3: İşlemler Operating System Concepts with Java 8th Edition 3.1 Silberschatz, Galvin and Gagne 2009

BİLGİSAYAR TEMELLERİ VE PROGRAMLAMAYA GİRİŞ

Linux altında komut satırında...

Qt ile Bir Ağ Uygulaması

C++ Giriş Ders 1 MSGSU Fizik Bölümü Ferhat ÖZOK Kullanılacak kaynak: Published by Juan Soulié

Scream! e gelen veri akışlarından bazılarını diğer bir kurum yada bilgisayarla paylaşmak için kullanılabilir.

10. DOSYA GİRİŞ ÇIKIŞ FONKSİYONLARI

Bilgisayar İşletim Sistemleri BLG 312

Komutlar (Devam) ls -a > deneme (ls -a komutunun çıktısı deneme isimli. ls -a >> deneme (ls -a komutunun çıktısı deneme

Göstericiler (Pointers)

İşletim Sistemi. BTEP205 - İşletim Sistemleri

Bölüm 10: PHP ile Veritabanı Uygulamaları

BLGM 344 DENEY 3 * AĞ PROGRAMLAMAYA GİRİŞ

Sınav tarihi : Süre : 60 dak. c) En başta #include<stdio.h> yazılmamıştır. c) zt d) Pi e) X0

KOCAELİ ÜNİVERSİTESİ MÜHENDİSLİK FAKÜLTESİ

Diziler. Yrd.Doç.Dr.Bülent ÇOBANOĞLU

FONKSİYONLAR. Gerçek hayattaki problemlerin çözümü için geliştirilen programlar çok büyük boyutlardadır.

BASİT C PROGRAMLARI Öğr.Gör.Dr. Mahmut YALÇIN

Öğr.Gör. Gökhan TURAN Gölhisar Meslek Yüksekokulu

BMS-302 İleri Web Programlama. İş Parçacığı (Thread) ve Soket (Socket) Programlama

İşletim Sistemleri. Hazırlayan: M. Ali Akcayol Gazi Üniversitesi Bilgisayar Mühendisliği Bölümü

Transkript:

İşletim Sistemleri Dr. Binnur Kurt binnur.kurt@gmail.com Omega Eğitim ve Danışmanlık http://www.omegaegitim.com 1 S a y f a

İÇİNDEKİLER 1. İşletim Sistemi 2. Kabuk 3. 4. İplikler 5. Arası İletişim 6. İş Sıralama 7. Ölümcül Kilitlenme 8. Çok İplikli Programlama 9. Bellek Yönetimi 10. Dosya Sistemi 11. Soket Haberleşme 2 S a y f a

BÖLÜM 3 Bölümün Amacı Bölüm sonunda aşağıdaki konular öğrenilmiş olacaktır: Proses ve prosesin durumları Linux da proses yönetimi arasında ebeveyn-çocuk ilişkisi Linux da çok prosesli uygulama geliştirme 3 S a y f a

3.1 Giriş İşletim sisteminin temel görevinin başta işlemci olmak üzere sistem kaynaklarını paylaştırmak olduğunu söylemiştik. İşletim sistemi tasarlanırken bir dizi genel tasarım hedefleri gözetilir. Bu isterlerin başında çok görevlilik gelir. İşletim sisteminin birden fazla görevi çalıştırması istenir. İşletim sistemi üzerinde çok sayıda uygulamanın çalışması istenir. Bu çalışan uygulamalar, işletim sisteminde, proses olarak adlandırılır. Burada işletim sistemi, tek ya da çok çekirdekli ya da işlemcili bir sistem üzerinde çalışıyor olabilir. Eğer tek işlemci yada çekirdek varsa aynı anda birden fazla proses çalışamaz. Çekirdek içinde proses sıralayıcı tarafından yönetilen bir önceliklendirilmiş kuyruk bulunur. Her proses belirli bir süre işlemciyi kullanır ve süresi dolduğunda işlemciyi terk eder. Bazen bir prosesin zamanı dolmasa da işlemciyi terk etmesi gerekebilir. Bu konuyu daha sonra daha detaylı inceleyeceğiz. Kuyruktaki proseslerden biri, işlemciyi bir sonra kullanacak proses olarak seçilir ve işlemci ona verilir. İşlemciyi terk eden proses bu önceliklendirilmiş kuyruktaki yerini alır ve sıra tekrar kendisine gelen kadar bekler. Böylelikle prosesler işlemciyi zamanda paylaşarak ve vakit buldukça çalışarak ellerindeki işleri tamamlamaya çalışırlar. Birden fazla çekirdek yada işlemcinin olduğu sistemlerde, çekirdek sayısı kadar kuyruk bulunur ve çekirdek sayısı kadar proses paralel olarak çalışabilir. 3.2 Proses Modeli Her bir uygulamanın çalıştırılması için bir prosesin yaratılması gerektirir. Ama bir uygulama çok prosesli olabilir. Bir proses bir ya da daha fazla çocuk proses yaratabilir. Böylelikle prosesler arasında ebeveyn çocuk ilişkisi yaratılmış olunur. Proses yaratıldığında bellekte proses için yer ayrılır. Bunun dışında çekirdek her bir proses için proses ile ilgili bilgileri sakladığı bir tablo oluşturur. Bu tablo proses tablosu olarak adlandırılır. Prosesin bellek modeli bir işlemciden diğerine değişmekle birlikte genel olarak Şekil-3.1 de verilen bir modele sahiptir. Burada Yığın (=Stack) yerel değişkenlerin, fonksiyon çağrılarında parametre aktarımı, dönüş adresinin ve dönüş değerinin saklanması için kullanılır. Yığının çalışması otomatik olarak gerçekleşir. Yerel değişkenler erimi başladığı yerde otomatik olarak yığında yaratılır, erimi dışına çıkıldığında ise yine otomatik olarak yok edilir. Bu yüzden bu tür değişkenler bazen geçici ya da otomatik değişken olarak da adlandırılır. Heap, dinamik bellek kullanımı için kullanılır. Bu alanın yönetiminden programcı sorumludur. Programcı, C de malloc() ve free() fonksiyonlarını, C++ da ise new ve delete operatörlerini kullanarak ihtiyacı kadar alanı alır ve kullanımı bitince ise aldığı alanı geri vermekle sorumludur. Bu söylemesi kolay ancak gerçeklemesi zor bir sorumluluktur. Bu nedenle C/C++ ile geliştirilen uygulamalarda dikkat edilmez ise bellek kaçağı oluşabilir. Bu özellikle servis tipi hiç sonlamayacak biçimde tasarlanan yazılımlar için büyük sorun oluşturur. Birkaç sekizlik bir kaçak, uzun dönemde yetersiz bellek hatası alınmasına neden olabilir. Text alanda fonksiyonlar yer alır. Data bölmesinde ise global değişkenler ve fonksiyonlarda static olarak tanımlanan değişkenler saklanır. 4 S a y f a

1 int x; 2 static int b = 4; 3 4 main() { 5 int y; 6 static int z; 7 8 y = b; 9 z = foo(y); 10 11 12 foo( int p ) { 13 int a; 14 a = p + 2; 15 return(a); 16 Stack Heap Data Text main() y foo() p a x b z main() { foo() { Şekil-3.1 Proses Bellek Modeli uygulamaların görevlerini kodlama için ağır sıklet elemanlardır. Bir proses fork() sistem çağrısını kullanarak çocuk proses yaratabilir. fork sistem çağrısı prosesin bellek görüntüsünün bire bir kopyasını çıkarır. Bu nedenle fork ile proses yaratmak maliyetlidir. Diğer bir maliyet bağlam anahtarlamada karşılaşılır. İşlemciyi kullanan proses süresi dolup işlemciyi terk ederken sıra tekrar kendisine geldiğinde kaldığı yerden devam edebilmesi için bağlamının saklanması gerekir. Bağlam, saklayıcılar, yığın göstergesi, program sayacı gibi işlemci içindeki elemanlardan oluşur. Bunlar bellekte saklanır. Böylelikle sıra tekrar kendisinde geldiğinde, prosesin bellekte saklanan bu bağlamı işlemciye geri yüklenerek, prosesin kaldığı yerden devam etmesi sağlanır. Prosesin bağlamı kalabalık olduğu için anahtarlama maliyeti de yüksektir. Bu yüzden çok prosesli yapıya farklı bir seçenek olarak çok lifli (=thread) yapılar kullanılabilir. Lifler proseslere göre hafif sıklet elemanlardır. Bir lif yaratıldığında onun için sadece yeni bir yığın yaratılır. Bir lif prosesin heap, text ve data alanlarını paylaşır. Her lifin ise kendi yığını vardır. Linux da yaratılabilecek proses sayısının ve yığın büyüklüğünün bir değeri ve sınırı vardır. Bu sınırları ulimit komutunu kullanarak öğrenebilir ve yine bu komutu kullanarak değiştirebiliriz: [student@server1 ~]$ ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 15781 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 5 S a y f a

pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 1024 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited Bu değerleri değiştirmek için komutun çıktısında listenen ile başlayan parantez içinde yazılı olan seçenek kullanılır. Örneğin bir kullanıcının yaratabileceği proses sayısı yukarıdaki listeden 1024 olarak okuyoruz. Bunu 2048 olarak değiştirmek için ulimit u 2048 komutunu çalıştırıyoruz: [student@server1 ~]$ ulimit -u 1024 [student@server1 ~]$ ulimit -u 2048 [student@server1 ~]$ ulimit -u 2048 Her bir lif yaratıldığında kendi yığını ile yaratılıyordu. Bu yığının boyutunu yukarıdaki komut çıktısından 8M olarak okuyoruz. Bunu 1M olarak değiştirmek için ulimit s 1024 komutunu çalıştırıyoruz: [student@server1 ~]$ ulimit -s 8192 [student@server1 ~]$ ulimit -s 1024 [student@server1 ~]$ ulimit -s 1024 Linux da uygulama geliştirmek için aşağıdaki modellerden biri kullanılır. i. Çok Prosesli Programlama Modeli ii. Tek Prosesli Çok Lifli Programlama Modeli iii. Çok Prosesli Çok Lifli Programlama Modeli Bu modellerin biri birlerine göre kazanım ve yitimleri vardır. Çok prosesli modelin yitimi proses yaratma ve prosesler arasında bağlam anahtarlama maliyetidir. Çok lifli programlamada lifler işlemciyi daha verimli kullanır. Üstelik lif yaratmak daha düşük maliyeti vardır. Buna karşılık liflerden biri başarısız olursa uygulama da başarısız olur ve sonlanması gerekir. Bu nedenle genellikle (iii) ile verilen modeli tercih edilir. Kritik görevler ayrı prosesler olarak kodlanır. Her bir proses liflerden oluşur. Örneğin Oracle veritabanı, chrome ve firefox web tarayıcıları bu modele göre gerçeklenmişlerdir. 3.3 Linux da le Çalışmak Sistemde çalışan tüm proseslerin listesini almak için ps komutunu fe seçeneği ile birlikte kullanıyoruz: student@server1 ~]$ ps -fe more UID PID PPID C STIME TTY TIME CMD root 1 0 0 10:22? 00:00:02 /sbin/init root 2 0 0 10:22? 00:00:00 [kthreadd] root 3 2 0 10:22? 00:00:00 [ksoftirqd/0]... root 17 2 0 10:22? 00:00:00 [watchdog/2] root 18 2 0 10:22? 00:00:00 [ksoftirqd/2] 6 S a y f a

root 19 2 0 10:22? 00:00:00 [migration/2]... pgrep komutu ile prosesler arasında arama işlemi yapılabilir. in bir kısmı arka planda çalışan proseslerdir. Bu proseslerin ismi d ile biter. Sonu d ile biten proseslerin listesini almak için pgrep i kullanabiliriz: [student@server1 ~]$ pgrep -l "d$" 2 kthreadd 10 rcu_sched 32 kintegrityd 33 kblockd... 3493 gvfsd 3531 restorecond 3535 vmtoolsd Burada $ özel bir semboldür ve katarın sonunu ifade eder. Komutun çıktısında ilk sütun proses kimlik numarasını ve ikinci sütun ise prosesin adını göstermektedir. i sonlandırmak için kill komutundan yararlanılır. kill komutu bir proses sinyal göndermek için kullanılır. Bir proses gönderilebilecek sinyallerin listesini almak için kill l komutunu kullanıyoruz: Bu sinyallerden 9 (SIGKILL) sinyalini alan bir proses doğrudan sonlanır: [student@server1 ~]$ for i in 1 2 3 ; do gcalctool & done [1] 12358 [2] 12359 [3] 12360 [student@server1 ~]$ kill -9 12358 [student@server1 ~]$ kill -9 12359 [1] Killed gcalctool [student@server1 ~]$ kill -9 12360 [2]- Killed gcalctool [student@server1 ~]$ [3]+ Killed gcalctool i proses ismi ile sonlandırmanın yolu pkill komutunu kullanmaktır: 7 S a y f a

[student@server1 ~]$ for i in 1 2 3 ; do gcalctool & done [1] 12374 [2] 12375 [3] 12376 [student@server1 ~]$ pkill gcalctool [student@server1 ~]$ [1] Terminated gcalctool [2]- Terminated gcalctool [3]+ Terminated gcalctool [student@server1 ~]$ arasında kimlik numarası 1 olan proses özel bir prosestir. init proses olarak adlandırılır. Tüm başlangıç işlemlerinden ve yapılandırmadan sorumludur. Başlangıç işlerinin yapılandırılmasından sorumlu dosya ise /etc/inittab dosyasıdır. Burada çalışma düzeyleri (=run level) tanımları yer alır. Her bir servisin hangi çalışma düzeyinde çalışacağı ise chkconfig komutu ile listelenebilir ve düzenlenebilir. Aşağıdaki örnekte mysql servisinin çalışma düzeyleri listeleniyor ve daha sonra tüm düzeylerde kapatılıyor. [student@server1 ~]$ chkconfig --list mysql mysql 0:off 1:off 2:on 3:on 4:on 5:on 6:off [student@server1 ~]$chkconfig --level 2345 mysql off [student@server1 ~]$ chkconfig --list mysql mysql 0:off 1:off 2:off 3:off 4:off 5:off 6:off Çalışma düzeyleri arasında geçiş için ise init komutundan yararlanılır. Klasik Unix sistemlerinde 5 çalışma düzeyi yer alır. 1 den 5 e doğru yeni servisler açılır. 5 den 1 e doğru servisler kapatılır. 1 düzeyinde tüm bilgisayar ağı kapalıdır ve çekirdek tek kullanıcılı olarak çalışır. Sisteme saldırı olduğunda ya da yeni bir çekirdek kurulması gerektiğinde işletim sistemi 1 düzeyine init 1 komutu ile indirilir. 1 düzeyinden 3 düzeyine çıkmak için init 3 komutu çalıştırılır. init 0 sistemi kapatırken init 6 işletim sistemini yeniden başlatır. 2 düzeyinde sistem çok kullanıcılı olur ve ağ erişilebilir. 3 düzeyinde NFS yeteneği gelir. 5 düzeyinde ise X11 sunucusu çalışır. X11 sunucusu grafik arayüzün çalışmasını sağlar. 3.4 Linux da Proses Yaratılması Linux da proses yaratmak için fork sistem çağrısını kullanıyoruz. fork sistem çağrısı yapıldığında çekirdeğin yürüttüğü işlemler: Proses tablosunda yer ayırılır Çocuk prosese sistemde tekil yeni bir kimlik numarası atanır Anne prosesin bağlamının kopyası çıkarılır. Dosya erişimi ile ilgili sayaçları düzenlenir fork() sistem çağrısı, anneye çocuğun kimliğini, çocuğa da 0 değerini döndürür. fork() sistem çağrısı, eğer proses yaratılırken hata durumu oluşursa, -1 değerini döndürür. fork() sistem çağrısının kullanıldığı basit bir örnek Kod 3.1 de verilmiştir. 8 S a y f a

Kod 3.1: #include <unistd.h> #include <stdio.h> int f; int main (void){ printf("program çalışıyor: Kimliğim= %d\n", getpid()); f=fork(); if (f==0) /*çocuk*/ { sleep(1); printf("\nben çocuk. Kimliğim= %d", getpid()); printf("\nannemin kimliği= %d\n", getppid()); exit(0); else if (f>0)/* anne */ { printf("\nben anne. Kimliğim= %d", getpid()); printf("\nannemin kimliği= %d", getppid()); printf("\nçocuğumun kimliği= %d\n", f); sleep(2); printf("\nbitti.\n"); exit(0); return(0); 3.5 Linux da Proses Sonlandırılması Bazen bir proses elindeki işi bitirmeden sonlanması gerekir. Genellikle bu durum kritik bir hata oluştuğunda gerçekleştirilir, hata iletisini kayda alıp proses sonlandırılır. Bu gibi durumlarda exit, _exit, atexit ve abort çağrılarını kullanıyoruz: i. exit() stdio nun tampon bellek alanlarını giriş/çıkış cihazlarına yazar ve uygulamayı _exit() çağrısı ile sonlandırır. void exit(int status); ii. _exit() Tüm açık dosyaları kapatır ve prosesi sonlandırır. Ebeveyn prosese SIGCHLD sinyali gönderir. Sinyaller prosesler arasında haberleşme için kullanılan tekniklerden biridir. Unix işletim sistemin bir prosese gönderilebilecek 9 S a y f a

proseslerin listesini almak için kill l komutu kullanıldığını daha önce çalışmıştık. Burada her bir sinyalin önceden tanımlı bir anlamı bulunmaktadır. void _exit(int status); iii. atexit() Proses sonlanırken çalıştırılmak üzere bir fonksiyonu kaydeder. Bu fonksiyon genellikle alınan sistem kaynaklarını serbest bırakacak kodu içerir. Kaynağa örnek olarak veritabanı bağlantısı ve soket verilebilir. Kod 3.2 de atexit çağrısının kullanımına ilişkin örnek bir uygulama verilmiştir. int atexit(void (*func)(void)); iv. abort() Tüm dosyaları kapatır, prosesi sonlandırır ve hata ayıklamada kullanılmak üzere prosesin bellek dökümünü bir dosyaya alır. Bu dosya daha sonra bir hata ayıklama aracı ile açılarak, hatanın kaynağı bulunmaya çalışılır. Dolayısı ile abort çağrısı sadece hata ayıklama amacıyla kullanılmalıdır. void abort(void); Kod 3.2: #include <string.h> #include <unistd.h> void cleanup() { char *message = "cleanup invoked\n"; write(stdout_fileno, message, strlen(message)); main() { atexit(cleanup); exit(0); 3.6 Proses Kimliğine Ulaşmak Bazen çalışmakta olan prosesin kimlik bilgisine erişmek gerekebilir. Bu durumda getpid, getppid, getpgrp ve getpgid fonksiyonları kullanılır. Şimdi bu fonksiyonların işlevlerine bir bakalım: 1. getpid() Çalışmakta olan prosesin kimlik numarasını verir. 10 S a y f a

pid_t getpid(void); 2. getppid() Çalışmakta olan prosesin ebeveyn prosesinin kimlik numarasını verir. pid_t getppid(void); getpid ve getppid çağrılarının kullanıldığı basit bir örnek Kod-3.3 de verilmiştir. 3. getpgrp() Prosesin yer aldığı grubun grup numarasını verir. #include <sys/types.h> #include <unistd.h> pid_t getpgrp(void); 4. getpgid() Proses grubunun kimlik numarasını verir. pid_t getpgid(pid_t pid); int setpgid(pid_t pid, pid_t pgid); Komut satırında ls sort uniq komutu çalıştırılırsa, 3 proses yaratılır ve bu prosesler aralarında boru (=pipe) olarak adlandırılan özel bir veri yapısı üzerinden haberleşirler: [student@server1 ~]$ ls sort uniq Desktop Documents Downloads... Bu üç proses ls, sort ve uniq komutlarına karşılık olarak yaratılır. Bu üç proses bir grup oluşturur (Şekil-3.2). Bu grubun kimliğine ulaşmak için getpgid çağrısını kullanıyoruz. Örneğe baktığımızda ls prosesinin kimliği 108, sort prosesinin kimliği 549 ve uniq prosesinin kimliği 3615 dir. Proses grubunun kimliği ise 240 tır. ls sort uniq PID 108 549 3615 PGID 240 240 240 Proses grup 240 549 3615 Şekil-3.2 Grup prosesler ve kimlik numaraları 108 Grup lideri 11 S a y f a

Kod 3.3: #include <unistd.h> #include <stdio.h> int main() { printf("my pid is: %d\n", getpid()); printf("my parent pid is: %d\n", getppid()); 3.7 Bir Prosesin Sonlanmasını Beklemek Ebeveyn prosesin sonlanmadan önce gerçekleştirmesi gereken bir sorumluluğu bulunmaktadır. Yarattığı çocuk proseslerin sonlanmasını beklemelidir. İşletim sistemi çekirdeği yaratılan her bir proses ile ilgili bir kayıt tutmaktadır. Normalde bir proses sonlandığında bu kayıt otomatik olarak silinir. Ancak çocuk prosesin sonlanma durumlarını izlenebilmesi için çocuk proses sonlandığında proses tablosundan kaydı silinmez. Bu sorumluluk ebeveyn prosese aittir. Ebeveyn proses bu sorumluluğunu wait ve waitpid çağrıları ile yerine getirir. Eğer ebeveyn proses bu sorumluluğunu yerine getirmez ve çocuk prosesin sonlanmasından önce sona ererse, çocuk prosesle ilgli bilgiler proses tablosundan silinemez. Unix işletim sisteminde, bu durumdaki prosesler, zombi proses olarak adlandırılır. 1. wait() Herhangi bir çocuk proses sonlandığında, sonlanan çocuk prosesin kimlik numarası ile dönülür. #include <sys/types.h> #include <sys/wait.h> pid_t wait(int *stat_loc); 2. waitpid() waitpid çağrısında wait çağrısından farklı olarak belirli bir prosesin sonlanması beklenebilir. #include <sys/types.h> #include <sys/wait.h> pid_t waitpid(pid_t pid,int *stat_loc,int options); Birinci parametrenin değerine farklı tercihler verilebilir: i. pid = -1 Herhangi bir çocuk proses sonlandığında waitpid çağrısından sonlanan çocuk prosesin kimlik numarası ile dönülür. ii. pid >0 Birinci parametrenin bu değeri sonlanması beklenen prosesin kimliğini tanımlar. iii. pid = 0 12 S a y f a

Çağıran prosesin bulunduğu proses grubundaki herhangi bir proses sonlandığında döner. iv. pid < 0 Birinci parametre olarak negatif bir sayı verildiğinde, bu sayının mutlak değerinin tanımladığı proses grubundan, herhangi bir proses sonlandığında, sonlanan prosesin kimlik numarası ile döner. waitpid çağrısı bloke çalışır. İstenilen proses sonlanana kadar çağrıyı yapan proses askıda kalır. Bu bazen istenmeyen durumdur. Üçüncü parametre olarak WNOHANG değeri verilirse, çağrının yapıldığı anda sonlanan herhangi bir proses yoksa, çağrıyı yapan proses çalışmaya devam eder, askıya alınmaz. Bu şekilde yoklamalı çalışılabilir. waitpid çağrısının kullanıldığı bir örnek Kod-3.4 de verilmiştir. Örnek uygulamada önce bir çocuk proses oluşturmakta ve ardından sonlanmasını beklemektedir. Kod 3.4: #include <sys/types.h> #include <sys/wait.h> #include <stdio.h> #include <unistd.h> int main() { pid_t pid; int status; /* fork() a child */ switch(pid = fork()) { case -1: perror("fork"); exit(1); /* in child */ case 0: execlp("ls", "ls", "-F", (char *)NULL); perror("execlp"); exit(1); /* parent */ default: break; if (waitpid(pid, &status, 0) == -1) { perror("waitpid"); exit(1); 13 S a y f a

if (WIFSIGNALED(status)) { printf("ls terminated by signal %d.\n", WTERMSIG(status)); else if (WIFEXITED(status)) { printf("ls exited with status %d.\n", WEXITSTATUS(status)); else if (WIFSTOPPED(status)) { printf("ls stopped by signal %d.\n", WSTOPSIG(status)); return 0; 14 S a y f a