Çok işlemcili bir sistemde, işletim sistemi sistemin en verimli çalışmasını mümkün kılan bir yolla farklı süreçleri mevcut işlemcilere dağıtır. Zamanlama işlevselliğini genişleterek hangi süreçlerin ve evrelerin çalışabileceği geçtiğimiz bölümlerde açıklanmıştı. Fakat hangi işlemcinin sonuçta hangi süreç ya da evreyi çalıştıracağı konumuzun dışındadır.
Bir yazılımın sistemi bu bakımdan denetimi altına almak zorunda bırakan bazı sebepler vardır:
Mutlak olarak kritik bir işlem yürütme durumunda olan bir süreç ya da evre hiçbir şart altında durdururulmamalı veya işlemci özkaynaklarını kullanarak başka süreçler tarafından engellenmemelidir. Bu durumda özel süreç için, hiçbir süreç ya da evre tarafından kullanılmasına izin verilmeyen bir işlemci tahsis edilmelidir.
Belirli özkaynaklara (RAM, G/Ç portları) farklı işlemcilerden erişim maliyetleri farklıdır. Böyle bir duruma NUMA (Non-Uniform Memory Architecture -- Tektip olmayan bellek mimarisi) makinelerde rastlanır. Tercihan, belleğe yerel olarak erişilmelidir fakat bu gereksinim genelde zamanlayıcıya görünür değildir. Bundan dolayı kullanılan belleğe yerel erişime sahip işlemcilerin bir sürece ya da evreye ayrılması başarımın belirgin biçimde artmasına yardımcı olur.
Çalışma anında denetim altında özkaynak ayrılması ve toparlama çalışmalarında (örn, çöp toplama) başarım işlemcilerin yerel işlem yapmasına bağlıdır. Eğer özkaynaklar farklı işlemcilerin rasgele erişimine karşı korunmamışsa, bu, kilitleme maliyetlerini düşürmeye yardımcı olur.
Şimdiye kadar POSIX standardı bu sorunun çözümüne pek yardımcı olmadı. Linux çekirdeği, bir işlemci için akrabalık kümeleri belirtilmesini mümkün kılan bir arayüz ailesi sağlar. Zamanlayıcı süreç ya da evreyi işlemciler üzerinde belirtilen akrabalık maskesine göre zamanlar. GNU C kütüphanesindeki arayüzler Linux çekirdeğindeki arayüz biraz genişletilerek tanımlanmıştır.
Bu veri türü her biri bir işlemciyi ifade eden bir bit kümesidir. İşlemcilerin bit kümesinin hangi bitleriyle eşleneceği sisteme bağlıdır. Veri türünün genişliği sabittir; sistemdeki işlemcileri ifade etmek için veri türünün genişliğini yetersiz kaldığı durumda başka bir arayüz kullanılmalıdır.
Bu veri türü bir GNU oluşumudur ve sched.h dosyasında tanımlanmıştır.
Bit kümesiyle çalışmak, bitleri belirtmek ve sıfırlamak için bazı makrolar tanımlanmıştır. Makroların bazıları parametre olarak bir işlemci numarası alır. Burada önemli olan bit kümesi genişliğinin aşılmamasıdır. Bu makro cpu_set_t bit kümesindeki bitlerin sayısını belirler:
Bir cpu_set_t nesnesi ile elde edilebilecek işlemci sayısıdır.
cpu_set_t veri türü şeffaf olmadığından bu veri türü ile ilgili çalışmalar aşağıdaki dört makro ile yürütülmelidir.
void CPU_ZERO | (cpu_set_t *küme) |
makro
Bu makro küme işlemci kümesini bir boş küme olarak ilklendirir.
Bu makro bir GNU oluşumudur ve sched.h dosyasında tanımlanmıştır.
void CPU_SET | (int işlemci,
cpu_set_t *küme) |
makro
işlemci işlemcisini küme işlemci kümesine ekler.
Defalarca işleme sokulacağından işlemci parametresinin yan etkilere sebep olmayacak şekilde belirtilmesi önemlidir.
Bu makro bir GNU oluşumudur ve sched.h dosyasında tanımlanmıştır.
void CPU_CLR | (int işlemci,
cpu_set_t *küme) |
makro
işlemci işlemcisini küme işlemci kümesinden kaldırır.
Defalarca işleme sokulacağından işlemci parametresinin yan etkilere sebep olmayacak şekilde belirtilmesi önemlidir.
Bu makro bir GNU oluşumudur ve sched.h dosyasında tanımlanmıştır.
int CPU_ISSET | (int işlemci,
cpu_set_t *küme) |
makro
Eğer işlemci işlemcisi küme işlemci kümesinin bir üyesi ise bu makro sıfırdan farklı bir değerle (doğru), değilse sıfırla (yanlış) döner.
Defalarca işleme sokulacağından işlemci parametresinin yan etkilere sebep olmayacak şekilde belirtilmesi önemlidir.
Bu makro bir GNU oluşumudur ve sched.h dosyasında tanımlanmıştır.
İşlemci bit kümeleri ya sıfırdan oluşturulur ya da o an kurulu bir akrabalık maskesi olarak sistemden alınır.
int sched_getaffinity | (pid_t pid,
size_t kümegenişliği,
cpu_set_t *küme) |
işlev
Bu işlev işlemci akrabalık maskesini kimliği pid ile belirtilen süreç ya da evre için genişliği kümegenişliği bayt olarak belirtilen ve küme ile gösterilen bir nesne olarak döndürür. İşlev başarılı olduğunda daima cpu_set_t nesnesindeki tüm bitleri ilklendirir ve sıfırla döner.
Eğer, pid bir süreç ya da evreye karşılık değilse ya da işlev bir sebeple başarısız olmuşsa -1 ile döner ve errno değişkenine hata durumu atanır.
- ESRCH
Belirtilen kimliğe sahip bir süreç ya da evre yok.
- EFAULT
küme göstericisi geçerli bir nesneyi göstermiyor.
Bu işlev bir GNU oluşumudur ve sched.h dosyasında bildirilmiştir.
Bunun, farklı POSIX evreleri için bilgi almak amacıyla kullanılmasının büyük ihtimalle taşınabilir olmayacağına dikkat çekmek gerekir. Bu durum için başka bir arayüz sağlanmalıdır.
int sched_setaffinity | (pid_t pid,
size_t kümegenişliği,
const cpu_set_t *küme) |
işlev
Bu işlev işlemci akrabalık maskesini kimliği pid ile belirtilen süreç ya da evre için genişliği kümegenişliği bayt olarak belirtilen ve küme ile gösterilen bir nesneye göre belirler. İşlev başarılı olduğunda sıfırla dönecek ve zamanlayıcı bu akrabalık bilgisini gelecekte hesaba katacaktır.
İşlev bir sebeple başarısız olmuşsa -1 ile döner ve errno değişkenine hata durumu atanır.
- ESRCH
Belirtilen kimliğe sahip bir süreç ya da evre yok.
- EFAULT
küme göstericisi geçerli bir nesneyi göstermiyor.
- EINVAL
Bit kümesi geçersiz. Bu, akrabalık kümesindeki bir işlemcinin süreç ya da evre için bırakılmamış olabileceği anlamına gelebilir.
Bu işlev bir GNU oluşumudur ve sched.h dosyasında bildirilmiştir.