UNIX Türevi Sistemlerde Proses ID Kavramı

Transkript

UNIX Türevi Sistemlerde Proses ID Kavramı
UNIX Türevi Sistemlerde Proses ID Kavramı
Kaan Aslan
12 Kasım 2007
UNIX türevi sistemlerde her prosesin sistem genelinde tek olan bir id değeri
vardır. Proses üzerinde işlem yapan POSIX fonksiyonları (tabi sistem fonksiyonları
da) bizden prosesin id değerini ister, bu id değerini anahtar olarak kullanarak proses
kontrol bloğuna erişir. Prosese ilişkin kritik bilgilerin büyük bölümünün proses kontrol
bloğunda tutulduğunu biliyorsunuz. Örneğin prosese sinyal gönderen kill
fonksiyonunun prototipi şöyledir:
int kill(pid_t pid);
görüldüğü gibi fonksiyon bizden sinyal gönderilecek prosesin id değerini istiyor.
Fonksiyon aldığı bu pid değerinden hareketle prosesin kontrol bloğuna erişecek ve
proses için sinyal teslim işlemini yapacaktır.
Sistemdeki tüm proseslerin doğrudan ya da dolaylı üst prosesi olan init prosesinin
id değeri 1’dir. UNIX türevi sistemler genellikle yeni yaratılan proses için sonraki ilk
boş id değerini tahsis etmektedir. Örneğin init prosesinin id değeri 1 olduğuna göre,
sonra yaratılan proseslere sırasıyla 2, 3, 4, ... id değerleri atanacaktır.[2] Sistem
genelinde belli bir anda aynı id'ye sahip birden fazla proses bulunamaz. Şüphesiz, bir
proses sonlandığında -eğer onun id’si yaşamakta olan bir proses grubuna ilişkin
değilse- sistem artık o id’yi yeni yaratılacak prosesler için kullanabilmektedir.
UNIX türevi sistemlerde proses id değeri pid_t türüyle temsil ediliyor. POSIX
standartlarında pid_t türünün işaretli bir tamsayı türü olması gerektiği belirtilmiş,
ancak hangi tür olarak typedef edileceği sistemi gerçekleştirenlerin isteğine
bırakılmıştır. Pek çok UNIX türevi sistemde pid_t türü int olarak typedef edilmiştir.[1]
Prosesin id değerinden proses kontrol bloğuna nasıl erişilmektedir? Sistemdeki
tüm prosesleri tarayarak doğrusal bir arama yapmak yavaş bir yöntemdir. Pek çok
sistemde bu dönüştürmenin hızlı yapılabilmesi için bir hash tablosu kullanılır. Örneğin
tipik olarak hash tablosu bağlı listelerden oluşturulur (separate chaining). Proses id’si
bir hash fonksiyonuna sokularak tablo indeksi elde edilir. Tabloda o indeksteki bağlı
listede doğrusal arama yapılır.
Linux sistemlerinde proses id’sinden proses kontrol bloğunun elde edilme yöntemi
-diğer pek çok çekirdek özelliğinde olduğu- gibi versiyondan versiyona gittikçe
iyileştirilmiştir. İlk versiyonlarda hash mekanizması kullanılmıyordu. Sistemdeki tüm
prosesler uygun id’li olan bulunana kadar tek tek dolaşılıyordu (linear search). Daha
sonra hash tablosu kullanılmaya başlandı. Örneğin, 2.4’lü çekirdeklerde kullanılan
hash tablosu şöyledir:
1
Kaan Aslan Makale Arşivi – www.kaanaslan.net
struct task_struct *pidhash[PIDHASH_SZ];
gördüğünüz gibi hash tablosu task_struct göstericilerinden oluşuyor. Yani hash
tablosundaki bağlı liste düğümü olarak task_struct yapısının kendisi kullanılmıştır.
Bağlı listelere ilişkin bağlar da task_struct yapısı içerisindeki pidhash_next ve
pidhash_pprev elemanlarında tutulmaktadır:
struct task_struct {
...
struct task_struct *pidhash_next;
struct task_struct **pidhash_pprev;
...
};
Hash tablosunun görüntüsü aşağıdaki gibidir:
2.4’lü çekirdeklerdeki bu yaklaşım basit olmasına karşın aynı proses grubuna ilişkin
proseslerin bulunması ya da aynı prosesin thread’lerinin bulunması yavaştı. Bunu
kolaylaştırmak için 2.6’lı çekirdeklerde task_struct içerisinde 1 değil 4 ayrı bağ ve
toplamda da 4 ayrı hash tablosu kullanılmaya başlanmıştır:
static struct hlist_head *pid_hash[PIDTYPE_MAX];
Buradaki PIDTYPE_MAX değeri 4’tür. 4 ayrı hash tablosu sırasıyla proses id’ler,
proses grup id’leri, thread grup id’leri ve oturum (session) grup id’leri için
düzenlenmiştir.
2
Kaan Aslan Makale Arşivi – www.kaanaslan.net
Proses kontrol bloğunda da her hash tablosu için ayrı bağlar (toplamda 4 tane)
oluşturulmuştur:
struct task_struct {
...
struct pid pids[PIDTYPE_MAX];
...
};
struct pid {
int nr;
struct hlist_node pid_chain;
struct list_head pid_list;
};
3
Kaan Aslan Makale Arşivi – www.kaanaslan.net
Yapıdaki nr elemanı ilgili task_struct yapısına ilişkin pid numarasını, pid_chain aynı
hash değerine sahip olan proseslerin liste bağını, pid_list ise aynı gruba ilişkin olan
proseslerin liste bağını belirtir. Bu durumda örneğin, elimizde bir prosesin id’si varsa
biz o prosesin tüm thread’lerini elde etmek için önce 1 numaralı hash tablosunda
arama yaparız. İlgili task_struct nesnesini bulduktan sonra pid_list bağlı listesini
dolaşırız.
4 ayrı hash tablosu tutulmasının nedeni türe göre hızlı arama yapmaktır. Aslında
tek hash tablosu ve task_struct içerisinde 4’lü bağ da yeterlidir. Zaten 2.6’lı
çekirdeklerin son versiyonlarına doğru yine fikir değiştirildiğini görüyoruz. İşte son
versiyonlara doğru hash tablosu yine teke indirilmiştir. Bu yeni versiyonlarda
task_struct içersinde yine 4 bağ vardır.
CSD çekirdeğinde proseslerle thread’ler farklı veri yapılarında saklanır. Prosesler
PROCESS_TABLE, thread’ler THREAD_TABLE yapılarıyla temsil edilmektedir. Yani
proses kontrol bloğu kendi thread’lerini içerir. CSD çekirdeğinde Linux sistemlerinde
olduğu gibi proseslerle thread’ler aynı veri yapısını (task_struct) kullanmazlar. CSD
bu bakımdan Windows sistemlerindeki yaklaşıma daha yakındır. CSD çekirdeğinde
proses id’sinden PROCESS_TABLE adresinin bulunması Linux’un 2.4 çekirdeğine
benzer bir biçimde tek bir hash tablosu yoluyla yapılmaktadır.
[1]
Windows sistemlerinde proses id değeri ile prosesin handle değeri farklı anlamlara
gelmektedir. Proses handle değeri HANDLE türüyle (32 ve 64 bit sistemlerde void *
olarak typedef edilmiştir), id değeri ise DWORD türüyle temsil edilir. Prosesin handle
değeri proses handle tablosunda bir indeks belirtirken prosesin id ise tıpkı UNIX
türevi sistemlerde olduğu gibi sistem genelinde tek olan (unique) prosese özgü bir
değerdir. Bu sistemlerde proses işlemlerinin çoğu prosesin handle değeri ile yapılır.
[2]
POSIX standartları yeni yaratılan proses için ilk boş id değerinin atanacağına ilişkin
bir garanti vermemektedir.
4
Kaan Aslan Makale Arşivi – www.kaanaslan.net

Benzer belgeler