Bölüm 2: İşletim Sistemi Yapıları

İşletim Sistemleri · Çalışma Soruları
HizmetlerBağlama ve boruÇift mod ve zamanlayıcıSistem çağrılarıDosya tanımlayıcılarıÇekirdek yapılarıSanal makinelerBağlama ve yükleme
Sercan KÜLCÜ

Ç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
pipe34 komut arasında 3 bağlantı
fork4her komut ayrı bir süreç
execvp4her çocuk kendini komutla değiştirir
dup26cat: 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.
  • printf her 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 B)konum 0hedef

kaynak 10 000 baytlık dosyaya, hedef boş bir dosyaya açık; konum 0.

kaynak (10 000 B)3000 Bkonum 3000hedef3000 B

İlk read tamponu doldurur: 3000 B. Okunan kadar yazılır.

kaynak (10 000 B)3000 Bkonum 6000hedef6000 B

İkinci read: yine 3000 B; dosya konumu 6000.

kaynak (10 000 B)3000 Bkonum 9000hedef9000 B

Üçüncü read: 3000 B; dosyada 1000 B kaldı.

kaynak (10 000 B)1000 Bkonum 10000hedef10000 B

Dördüncü read yalnızca kalanı döndürür: 1000. write(hedef, buf, n) tamponun yalnızca dolu kısmını yazar.

kaynak (10 000 B)konum 10000hedef10000 BEOF

Beşinci read 0 döndürür: dosya sonu. Döngü biter ama bu çağrı da sayıldı.

kaynak (10 000 B)konum 10000hedef10000 BEOF

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?

/ev/yedeknotlar.txt → 70(girdi yok)i-node 70bağ sayısı = 1açık fd = 0bloklar: 3 blok

Dizin yalnızca (ad, i-node numarası) çiftleri tutar; dosyanın kendisi i-node 70’tedir.

/ev/yedeknotlar.txt → 70n.txt → 70i-node 70bağ sayısı = 2açık fd = 0bloklar: 3 blok

link aynı i-node’u gösteren ikinci bir ad ekler; veri kopyalanmaz, bağ sayısı 2 olur.

/ev/yedek(girdi yok)n.txt → 70i-node 70bağ sayısı = 1açık fd = 0bloklar: 3 blok

unlink yalnızca dizin girdisini siler; dosya n.txt adıyla yaşar.

/ev/yedek(girdi yok)n.txt → 70i-node 70bağ sayısı = 1açık fd = 1bloklar: 3 blok

open en küçük boş numarayı verir: fd = 3. Çekirdek i-node’u açık tutar.

/ev/yedek(girdi yok)(girdi yok)i-node 70bağ sayısı = 0açık fd = 1bloklar: 3 blok (adsız)

Son ad da silindi: bağ sayısı 0. Ama dosya hâlâ açık olduğu için bloklar serbest bırakılmaz.

/ev/yedek(girdi yok)(girdi yok)i-node 70bağ sayısı = 0açık fd = 1bloklar: 3 blok (adsız)

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.

/ev/yedek(girdi yok)(girdi yok)i-node 70bağ sayısı = 0açık fd = 0bloklar: serbest

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.

kullanıcı moduUygulamaDosya sun.Disk sür.mikro çekirdek (IPC)

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.

kullanıcı moduUygulamaDosya sun.Disk sür.mikro çekirdek (IPC)12ileti 1: 2 mod geçişi + 1 bağlam değiştirme

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).

kullanıcı moduUygulamaDosya sun.Disk sür.mikro çekirdek (IPC)12ileti 2: 2 mod geçişi + 1 bağlam değiştirme

Dosya sunucusu hangi bloğun okunacağını bulur ve disk sürücüsüne ileti yollar.

kullanıcı moduUygulamaDosya sun.Disk sür.mikro çekirdek (IPC)12ileti 3: 2 mod geçişi + 1 bağlam değiştirme

Sürücü, çekirdeğin izin verdiği G/Ç ile bloğu okur ve sonucu dosya sunucusuna iletir.

kullanıcı moduUygulamaDosya sun.Disk sür.mikro çekirdek (IPC)12ileti 4: 2 mod geçişi + 1 bağlam değiştirme

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.so gü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.

Son

Bölüm 2: İşletim Sistemi Yapıları: Çalışma Soruları
Konu anlatımı: İşletim sistemi yapıları sunumu · Terim sözlüğü
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.