Wednesday 12 December 2007

LINUX Çekirdeğini Anlamak - Süreçler 3

3.1.3 Süreçler Arasında Ebeveynlik İlişkileri (Parenthood Relationships Among Processes)
Bir program tarafından yaratılan süreçler ebeveyn/çocuk ilişkisine sahiptirler.
Bir süreç birden çok sayıda çocuk yaratabileceklerinden, bunlar kardeşlik ilişkisine sahip olurlar. Bu ilişkileri temsil etmek için bir süreç tanmlayıcıda çok sayıda alan kullanılması gerekir. Süreç 0 ve 1 çekirdek tarafından yaratılır; süreç 1 (sıfırla (init)) diğer bütün süreçlerin atasıdır.

Bir P sürecinin tanımlayıcısı aşağıdaki alanlara içerir:
p_opptr (doğal ebeveyn) (original parent)
p_pptr (ebeveyn) (parent)
p_cptr (çocuk) (child)
p_ysptr (daha genç kardeş) (younger sibling)
p_osptr (daha yaşlı kardeş) (older sibling)


Şekil 3-6. Beş süreç arasında ebeveynlik ilişkileri
Parenthood relationships among five processes

3.1.4 Bekleyiş Kuyrukları (Wait Queues)
Çalıştırışkuyruğu (runqueue) listesi bir GÖREV_ÇALIŞIYOR (TASK_RUNNING) halindeki bütün süreçleri biraraya getirir. Başka hallerdeki süreçleri gruplayışa gelince, çeşitli haller farklı tür ele alışı gerektirir, Linux’un aşağıdaki seçeneklerden birini tercih edişine yol açarak:

• GÖREV-DURDU (TASK_STOPPED) veya GÖREV_ZOMBİ (TASK_ZOMBIE) halindeki süreçler belirli listelere bağlanmaz. Bunları gruplamağa gerek yoktur, çünkü çocuk sürece erişmek için ebeveyn süreç tarafından ya süreç SüreçKimlikNo’su (PID) ya da süreç ebeveynlik ilişkileri kullanılabilir.

• GÖREV_KESİLEBİLİR (TASK_INTERRUPTIBLE) veya GÖREV_KESİLEMEZ (TASK_UNINTERRUPTIBLE) halindeki süreçler her biri belirli bir olaya (event) denk düşen çok sayıda alt sınıfa ayrılabilir. Bu durumda, süreç hali sürece çabukça erişmek (retrieve) için yeterli bilgi sağlamaz, bu yüzden ek süreç listeleri kullanmak gerekir. Bu ek listelere bekleyiş listeleri (wait queues) adı verilir.

Bekleyiş listeleri çekirdek içinde bir çok kullanımlara sahiptir, özellikle kesiş muamelesi (interrupt handling), süreç eşzamanlayışı (process synchronization), ve zamanlayış (timing) için. Bir süreç genellikle bir olayın gerçekleşişini beklemek zorundadır; bir disk işleminin bitişi, bir sistem kaynağının serbest bırakılışı, veya sabit aralık zamanın doluşu gibi… Bekleyiş kuyrukları olaylara bağlı koşullu bekleyişleri gerçekleştirir: belirli bir olayı beklemek isteyen bir süreç kendini bir bekleyiş kuyruğuna yerleştirir ve kontrolü serbest bırakır. Bunun yüzünden, bir bekleyiş kuyruğu bir koşul sağlandığında çekirdek tarafından uyandırılan bir grup uyuyan süreci temsil eder.

Bekleyiş kuyrukları elemanları süreç tanımlayıcılara işaret ediciler içeren çembersel listeler olarak gerçekleştirilir. Bir bekleyiş kuyruğunun her elemanı bekleyiş_kuyruğu (wait_queue) türündendir.

yapı görev_kuyruğu { struct wait_queue {
yapı görev_yapısı * görev; struct task_struct * task;
yapı bekleyiş_kuyruğu * sonraki; struct wait_queue * next;
}; };

Her bekleyiş kuyruğu bir bekleyiş kuyruğu işaret edicisi(wait queue pointer) tarafından belirlenir, ilk elemanın adresini taşıyan ya da eğer liste boş ise, boş işaret ediciyi taşıyan…
bekleyiş_kuyruğu (wait_queue) veri yapısı listedeki sonra gelen ilk elemana işaret eder, sonraki (next) alanı anlamsız (dummy) bir liste elemanına işaret eden son eleman hariç.
Anlamsız(dummy)’ın sonraki (next) alanı bekleyiş kuyruğundan bir işaret edici genişliği azını işaret eden bir değişken ya da alanın adresini taşır (İntel platformlarında bir işaret edici 4 byte uzunluğundadır). Böylece, bekleyiş kuyruğu listesi çekirdek fonksiyonları tarafından gerçek bir çembersel liste şeklinde değerlendirilebilir, son elemanın sonraki(next) alanı, bekleyiş kuyruğu işaretedicisi ile çakışan anlamsız(dummy) bekleyiş kuyruğu yapısına işaret ettiği için… (Şekil 3-7 ’ye bakınız).


Şekil 3-7. Bekleyiş kuyruğu veri yapısı
The wait queue data structure

bekleyişkuyruğunu_sıfırla (init_waitqueue()) fonksiyonu boş bir bekleyiş kuyruğunu sıfırlar; bekleyişkuyruğuna_ekle(kyrk, hane) (add_wait_queue(q,entry)) fonksiyonu hane(entry) adresli yeni haneyi bekleyiş kuyruğu işaretedicisi kyrk (q) ile belirlenen bekleyiş kuyruğuna ekler.


Bekleyiş kuyrukları önemli çekirdek fonksiyonları kadar kesiş muamele edicileri (interrupt handlers) tarafından da değiştirildikleri için, bu fonksiyon aşağıdaki işlemleri engellenmiş kesişlerle(disabled interrupts) çalıştırır:

3.1.5 Süreç Kullanım Sınırları (Process Usage Limits)
Süreçler kullanım sınırları (usage limits ) grupları ile ilişkilendirilirler, kullandıkları sistem kaynakları miktarını belirleyen.

Özellikle, Linux aşağıdaki sınırları tanır:
RLIMIT_CPU Süreç için Merkezi işlem Birimi zaman üst sınırı
RLIMIT_FSIZE İzin verilen dosya uzunluğu üst sınırı
RLIMIT_DATA Düz bellek (heap) büyüklüğü üst sınırı
RLIMIT_STACK Yığın(stack) büyüklüğü üst sınırı
RLIMIT_CORE Nüve dökümü (core dump) dosya büyüklüğü üst sınırı
RLIMIT_RSS Süreç tarafından sahip olunan sayfa çerçeveleri sayısı üst sınırı
RLIMIT_NPROC Bir kullanıcının sahip olabileceği en çok süreç sayısı
RLIMIT_NOFILE Açık dosya sayısı üst sınırı
RLIMIT_MEMLOCK Maximum size of nonswappable memory
RLIMIT_AS Süreç adres alanı büyüklüğü üst sınır