Bölüm 2: İşletim Sistemi Yapıları
Çoktan Seçmeli · Giriş
Soru 1: Aynı Kod, Farklı Sistem
İki işletim sisteminde dosya sistemi kodu aynı. Birinde bu kod çekirdek modunda çalışıyor ve diğer bileşenlerce doğrudan fonksiyon çağrısıyla kullanılıyor; ötekinde kullanıcı modunda ayrı bir süreç olarak çalışıyor ve iletiyle çağrılıyor. İki sistem asıl hangi açıdan farklıdır?
A: Bileşenlerin nerede çalışacağına (çekirdek / kullanıcı modu) ve nasıl haberleşeceğine (fonksiyon çağrısı / ileti) dair strateji işletim sistemi yapısıdır: ilki monolitik, ikincisi mikro çekirdek yaklaşımıdır. API ve disk biçimi iki sistemde aynı olabilir.
Çoktan Seçmeli · Hizmetler
Soru 2: Hangisi İS Hizmeti Değil?
İşletim sistemleri kullanıcıya ve programlara bir dizi hizmet sunar. Aşağıdakilerden hangisi bu hizmetlerden biri değildir?
C: Formül hesaplamak uygulamanın kendi mantığıdır; İS ona yalnızca CPU ve bellek sağlar. Program yürütme, iletişim ve hata algılama İS’nin standart hizmet gruplarındandır.
Çoktan Seçmeli · Temel Kavramlar
Soru 3: USB Belleği Bağlamak
Linux’ta mount /dev/sdb1 /mnt/usb komutundan sonra hangisi doğrudur?
D: UNIX’te tek bir dizin ağacı vardır; başka aygıtların dosya sistemleri bu ağaca bağlama noktalarından eklenir. Bağlama noktasının eski içeriği silinmez, yalnızca umount edilene kadar görünmez olur. Sürücü harfi Windows yaklaşımıdır.
Hesaplama · Temel Kavramlar
Soru 4: Boru Hattını Kurmak
Kabuk cat a.txt | sort | uniq -c | wc -l komutunu çalıştırıyor. Kabuk ve çocukları toplam kaç pipe(), kaç fork(), kaç execvp() ve kaç dup2() çağırır? Kabuk neden kendi elindeki boru uçlarını kapatmalıdır?
Cevabı göster
| çağrı | sayı | neden |
|---|---|---|
| pipe | 3 | 4 komut arasında 3 bağlantı |
| fork | 4 | her komut ayrı bir süreç |
| execvp | 4 | her çocuk kendini komutla değiştirir |
| dup2 | 6 | cat: stdout (1) · sort, uniq: stdin + stdout (2 + 2) · wc: stdin (1) |
Okuyucu, ancak borunun bütün yazma uçları kapanınca dosya sonu (read = 0) görür. Kabuk kendi kopyalarını kapatmazsa wc hiç bitmez; ayrıca her çocuk dup2’den sonra fazla uçları kapatır.
Çoktan Seçmeli · Koruma
Soru 5: Ayrıcalık Gerektirmeyen İşlem
Aşağıdaki işlemlerden hangisi ayrıcalıklı komut olmak zorunda değildir, yani kullanıcı modundaki bir program onu serbestçe yapabilir?
A: Saati okumak kimseye zarar vermez. Zamanlayıcıyı ayarlayan program CPU’yu tekeline alabilir, kesmeleri kapatan İS’yi devre dışı bırakır, sayfa tablosu yazmacını değiştiren başka süreçlerin belleğine erişir. Bu yüzden B, C ve D yalnızca çekirdek modunda çalışır.
Hesaplama · Koruma
Soru 6: Zamanlayıcıyı Kurmak
Donanım zamanlayıcısının sayacı 19,2 MHz’lik bir saatle her darbede 1 azalıyor ve sıfırda kesme üretiyor. Çekirdek saniyede 250 tik (250 Hz) istiyor. Sayaca hangi değeri yüklemelidir? Her tik kesmesinin işlenmesi 3 µs sürüyorsa CPU zamanının yüzde kaçı tiklere gider? 1000 Hz’te ne değişir?
Cevabı göster
- 250 Hz: 19 200 000 / 250 = 76 800 darbe; tik aralığı 4 ms.
- Ek yük: 250 × 3 µs = 750 µs/s → %0,075.
- 1000 Hz: sayaç 19 200, ek yük 3 ms/s → %0,3 (4 kat).
Sık tik daha ince zaman dilimi ve daha duyarlı çizelgeleme demektir; bedeli ek yük ve boşta bile uyanan CPU’dur (tickless mod bu yüzden vardır). Sayaca değer yüklemek ayrıcalıklı bir komuttur: kullanıcı programı zamanlayıcıyı durdurup CPU’yu tekeline alamaz.
Çoktan Seçmeli · Sistem Çağrıları
Soru 7: Hangisi Çekirdeğe Girmez?
Aşağıdaki işlemlerden hangisi çekirdeğe girmeden, yalnızca kütüphane koduyla tamamlanabilir?
B: atoi, strlen, sprintf yalnızca sürecin kendi belleğindeki veriyle çalışır. Dosya adını değiştirmek ve dosya açmak dosya sistemine, süreç oluşturmak çekirdek yapılarına dokunur; bunlar sistem çağrısıdır. printf da kütüphane fonksiyonudur ama tamponu boşaltırken write çağırır.
Kod Çıktısı · Sistem Çağrıları
Soru 8: Hangi Tanımlayıcı Numarası?
Program yeni başlamış; yalnızca 0, 1, 2 açık ve tüm dosyalar mevcut. Ekrana ne yazılır? d.txt dosyasına ne yazılır?
int a = open("a.txt", O_RDONLY); int b = open("b.txt", O_RDONLY); int c = dup(a); close(a); close(1); int d = open("d.txt", O_WRONLY); int e = dup(c); printf("%d %d %d %d %d\n", a, b, c, d, e);
Cevabı göster
Kural: open ve dup en küçük boş numarayı verir.
- a = 3, b = 4, c = dup(3) = 5. close(a) 3’ü boşaltır.
- close(1) standart çıktıyı kapatır → d = 1; e = dup(5) = 3.
printfher zaman fd 1’e yazar; fd 1 artık d.txt’dir.
Ekrana hiçbir şey yazılmaz; d.txt’ye 3 4 5 1 3 yazılır. Kabuğun > yönlendirmesi tam bu kurala dayanır.
Adım Adım Çalıştırma · Sistem Çağrıları
Soru 9: Kopyalama Döngüsü
kaynak 10 000 baytlık bir dosyaya, hedef boş bir dosyaya açık. Program ne yazdırır? read ve write için toplam kaç sistem çağrısı yapılır?
kaynak 10 000 baytlık dosyaya, hedef boş bir dosyaya açık; konum 0.
İlk read tamponu doldurur: 3000 B. Okunan kadar yazılır.
İkinci read: yine 3000 B; dosya konumu 6000.
Üçüncü read: 3000 B; dosyada 1000 B kaldı.
Dördüncü read yalnızca kalanı döndürür: 1000. write(hedef, buf, n) tamponun yalnızca dolu kısmını yazar.
Beşinci read 0 döndürür: dosya sonu. Döngü biter ama bu çağrı da sayıldı.
5 read + 4 write = 9 sistem çağrısı, her biri iki mod geçişi. Sabit 3000 bayt yazılsaydı hedef 12 000 B olurdu.
char buf[3000]; int okuma = 0, yazma = 0; long toplam = 0; ssize_t n; for (;;) { n = read(kaynak, buf, sizeof buf); okuma++; if (n <= 0) break; write(hedef, buf, n); yazma++; toplam += n; } printf("okuma=%d yazma=%d toplam=%ld\n", okuma, yazma, toplam);
Hesaplama · Sistem Çağrıları
Soru 10: Tampon Boyutunun Bedeli
Her sistem çağrısının yalnızca mod geçişi ve giriş/çıkış maliyeti 0,25 µs olsun. 2 MiB’lık bir dosya önce 1 baytlık, sonra 8192 baytlık tamponla read döngüsüyle okunuyor (dosya sonunu bildiren son çağrı dahil). Her durumda kaç read yapılır, bu ek yük ne kadardır?
Cevabı göster
- 2 MiB = 2 × 2²⁰ = 2 097 152 B.
- 1 B tampon: 2 097 152 + 1 = 2 097 153 çağrı → × 0,25 µs ≈ 524,3 ms.
- 8192 B tampon: 2 097 152 / 8192 = 256, + 1 = 257 çağrı → 64,25 µs.
Fark yaklaşık 8000 kattır. Bu yüzden stdio (fread, getc) kullanıcı alanında tamponlar ve çekirdeğe büyük parçalarla gider: getc çoğu zaman çekirdeğe hiç girmez.
Çoktan Seçmeli · Sistem Çağrıları
Soru 11: Başarısız exec
Programcı echo yerine yanlışlıkla ecoh yazmış; sistemde bu adla bir program yok. Program hangi satırları yazdırır?
int main(void) { printf("A\n"); fflush(stdout); pid_t p = fork(); if (p == 0) { execlp("ecoh", "ecoh", "B", NULL); printf("C\n"); exit(1); } int st; waitpid(p, &st, 0); printf("D%d\n", WEXITSTATUS(st)); return 0; }
B: execlp programı bulamayınca −1 döndürür ve çocuk sonraki satırdan devam eder: C’yi yazar, exit(1) ile biter. Ebeveyn bekler, çıkış kodu 1’i okur: D1. Başarılı bir exec geri dönmezdi; o zaman çıktı A, B, D0 olurdu. fflush, A’nın tamponda kalıp çocuğa kopyalanmasını önler.
Adım Adım Çalıştırma · Sistem Çağrıları
Soru 12: link ve unlink
Her satırdan sonra i-node 70’in bağ sayısı ve açık tanımlayıcı sayısı nedir? 6. satırdaki read başarılı olur mu? Dosyanın blokları ne zaman serbest kalır?
Dizin yalnızca (ad, i-node numarası) çiftleri tutar; dosyanın kendisi i-node 70’tedir.
link aynı i-node’u gösteren ikinci bir ad ekler; veri kopyalanmaz, bağ sayısı 2 olur.
unlink yalnızca dizin girdisini siler; dosya n.txt adıyla yaşar.
open en küçük boş numarayı verir: fd = 3. Çekirdek i-node’u açık tutar.
Son ad da silindi: bağ sayısı 0. Ama dosya hâlâ açık olduğu için bloklar serbest bırakılmaz.
read başarılıdır (dosya en az 100 B ise n = 100): açık tanımlayıcı i-node’a bağlıdır, ada değil.
Bağ sayısı ve açık sayısı ikisi de 0: i-node ve 3 blok ancak şimdi serbest kalır. Geçici dosyalar bu yöntemle oluşturulur.
/* başta: /ev/notlar.txt → i-node 70 */ link("/ev/notlar.txt", "/yedek/n.txt"); unlink("/ev/notlar.txt"); int fd = open("/yedek/n.txt", O_RDONLY); unlink("/yedek/n.txt"); ssize_t n = read(fd, buf, 100); close(fd);
Çoktan Seçmeli · Yapılar
Soru 13: Mikro Çekirdeğin Asıl Kazancı
Aşağıdakilerden hangisi mikro çekirdek yapısının bir avantajıdır?
C: Sürücüler ve dosya sistemi kullanıcı modunda ayrı süreçlerdir; biri çökünce çekirdek ve diğer hizmetler çalışmayı sürdürür (MINIX 3’ün reenkarnasyon sunucusu). Ayrıcalıklı kod küçüktür. A ve B’nin tersi doğrudur: IPC mikro çekirdeğin bedelidir; D monolitik çekirdeği anlatır.
Adım Adım Çalıştırma · Yapılar
Soru 14: Mikro Çekirdekte Bir Okuma
Mikro çekirdekte bir okuma isteği dört iletiyle tamamlanıyor; her ileti iki mod geçişi ve bir bağlam değiştirme gerektiriyor. Disk süresi hariç ek yük ne kadardır, monolitik çekirdekle karşılaştırın.
Monolitik çekirdekte okuma tek bir sistem çağrısıdır: girişte ve dönüşte birer mod geçişi, aradaki her şey çekirdek içi fonksiyon çağrısıdır.
Uygulama iletiyi gönderir: çekirdeğe tuzak (1), çekirdek dosya sunucusuna geçer (bağlam değiştirme) ve onu kullanıcı moduna döndürür (2).
Dosya sunucusu hangi bloğun okunacağını bulur ve disk sürücüsüne ileti yollar.
Sürücü, çekirdeğin izin verdiği G/Ç ile bloğu okur ve sonucu dosya sunucusuna iletir.
Dosya sunucusu 4096 baytı uygulamaya döndürür. Toplam 4 × 1,4 = 5,6 µs: monolitiğin 28 katı. Disk milisaniyeler sürdüğünde fark küçük kalır; önbellekten karşılanan küçük isteklerde belirleyicidir.
uygulama → dosya sun.: OKU(fd, 4096) dosya sun. → disk sür. : BLOK 812 disk sür. → dosya sun.: blok verisi dosya sun. → uygulama : 4096 bayt mod geçişi: 0,1 µs bağlam değiştirme: 1,2 µs monolitik: tek sistem çağrısı
Çoktan Seçmeli · Yapılar
Soru 15: Yüklenebilir Modül Nerede Çalışır?
Linux’ta modprobe ile çalışma sırasında yüklenen bir ağ kartı sürücüsü hangi modda ve hangi adres alanında çalışır?
D: Yüklenen modül çekirdeğin bir parçası olur ve çekirdeğin geri kalanıyla doğrudan fonksiyon çağrısıyla konuşur; arada IPC yoktur ve bir modül hatası tüm çekirdeği çökertebilir. Modüller Linux’u esnek yapar ama mikro çekirdeğe dönüştürmez: Linux modüler monolitiktir.
Çoktan Seçmeli · Sanal Makineler
Soru 16: Konteyner mi, Sanal Makine mi?
Aşağıdaki ifadelerden hangisi doğrudur?
C: Konteyner işletim sistemi düzeyinde sanallaştırmadır: süreçler ad alanları ile yalıtılır, cgroups ile sınırlanır; bu yüzden saniyenin altında başlar. B yanlıştır: Windows’ta Linux konteynerleri bir Linux sanal makinesinde (WSL 2) çalışır. D tip 1 hipervizörü anlatır.
Klasik Soru · Donanım ve Yapı
Soru 17: İki Çekirdek, Bir Liste
SMP bir sistemde iki çekirdek aynı anda ekle çağırıyor: CPU0 görev X’i, CPU1 görev Y’yi ekliyor; başta liste bas → A. Adımlar CPU0(1), CPU1(1), CPU0(2), CPU1(2) sırasıyla işlerse liste ne olur? Çözüm nedir?
struct gorev *bas; /* hazır listesi */ void ekle(struct gorev *g) { g->sonraki = bas; /* (1) */ bas = g; /* (2) */ }
Cevabı göster
- CPU0(1): X.sonraki = A. CPU1(1): Y.sonraki = A.
- CPU0(2): bas = X → X → A. CPU1(2): bas = Y → Y → A.
X listeden kaybolur: hiçbir göstericiden erişilemez, hiç çizelgelenmez. Sonuç adımların sırasına bağlıdır (yarış durumu).
SMP’de her CPU çekirdek kodunu çalıştırabildiği için ortak çekirdek yapıları kilitle (ör. spinlock) korunmalıdır: lock; (1); (2); unlock. Linux bu yüzden “büyük çekirdek kilidi”nden ince taneli kilitlere geçti.
Hesaplama · Bağlama ve Açılış
Soru 18: Statik mi, Dinamik mi?
Bir sunucuda C kütüphanesini kullanan 40 farklı program aynı anda çalışıyor; kütüphane kodu 2 MiB. Kütüphane statik bağlanırsa ve dinamik (paylaşımlı, libc.so) bağlanırsa bellekte kütüphane kodu için ne kadar yer gerekir? Kütüphanede bir güvenlik açığı kapatıldığında iki durumda ne yapılmalıdır?
Cevabı göster
- Statik: kod her çalıştırılabilir dosyaya kopyalanır → bellekte 40 × 2 MiB = 80 MiB (diskte de her dosya 2 MiB büyür).
- Dinamik: kod sayfaları salt okunur olduğundan tek kopya tüm süreçlere eşlenir → 2 MiB (+ her sürecin küçük, özel veri alanı).
- Yama: statikte 40 programın hepsi yeniden bağlanmalıdır; dinamikte yalnızca
libc.sogüncellenir, programlar yeniden başlatılınca yeni kodu kullanır.
Statik bağlamanın artısı bağımsızlıktır: program başka dosyaya gerek duymaz, yükleme anında sembol çözümü olmaz.