Muteksler
Önceki POSIX Evreleri Sonraki
Muteksler
Bir mutek bir Karşılıklı Dışlama (MUTual EXclusion) aygıtıdır ve paylaşılan veri yapılarını eşzamanlı değişikliklerden korumak için ve kritik bölümler ve görüntüleme birimlerini uygulamak için kullanışlıdır.
Bir muteksin iki durumu vardır: kilitsiz (herhangi bir evre tarafından sahiplenilmemiş) ve kilitli (bir evre tarafından sahiplenilmiş). Bir muteks hiçbir zaman aynı anda iki farklı evre tarafından sahiplenilemez. Kilitli bir muteksi kilitlemeye teşebbüs eden bir evre sahiplenen evre o muteksin kilidini açana kadar askıya alınır.
Muteks işlevlerinden hiçbiri bir iptal noktası değildir, hatta bir evreyi belirli aralılarla askıya alabilen pthread_mutex_lock bile. Evre işletilmeyi durdurmadan önce kilidinin açılması gereken muteksleri, iptal işleyicilerinin açmalarını sağlayarak, mutekslerin iptal noktalarındaki durumları önceden tahmin edilebilir. Sonuç olarak, ertelenmiş iptal kullanan evreler hiçbir zaman bir muteksi genişletilmiş zaman aralıklarıyla tutmamalıdırlar.
Muteks işlevlerini tek bir sinyal işleyiciden çağırmak güvenli değildir. Özellikle, tek bir sinyal işleyiciden pthread_mutex_lock veya pthread_mutex_unlock çağırmak, çağıran evreyi kısır döngüye sokabilir.
int pthread_mutex_init
(pthread_mutex_t            *muteks,
 const pthread_mutexattr_t *muteks_özelliği)
işlev
pthread_mutex_init muteks_özelliği ile mutex özellikleri belirtilen muteks ile gösterilen muteks nesnesini hazırlar. Eğer muteks_özelliği NULL ise, öntanımlı özellikler kullanılır.
LinuxThreads gerçeklemesi sadece bir muteks özelliğini desteklemektedir, bu "hızlı", "özyinelemeli" veya "hata denetimli" olan muteks türüdür. Mutex tipi, sahiplenildiği evre tarafından tekrar kilitlenebilirliğini belirler. Varsayılan "hızlı"dır.
pthread_mutex_t türündeki değişkenler de PTHREAD_MUTEX_INITIALIZER (zamanlı muteksler için), PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP (özyinelemeli muteksler için), PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP (hızlı muteksler için) ve PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP (hata denetimli muteksler için) sabitleri kullanılarak ilk değerleri statik olarak alabilirler.
pthread_mutex_init daima 0 ile döner.
int pthread_mutex_lock
(pthread_mutex_t *muteks)
işlev
pthread_mutex_lock verilen muteksi kilitler. Muteks kilitli değilse, kilitlenir, çağıran evre tarafından sahiplenilir ve pthread_mutex_lock hemen döner. Eğer muteks zaten başka bir evre tarafından kilitlendiyse, pthread_mutex_lock muteksin kilidi açılana kadar çağıran evreyi askıya alır.
Eğer muteks çağıran evre tarafından önceden kilitlenmişse, pthread_mutex_lock davranışı muteks türüne bağlıdır. Eğer muteks "hızlı" türdeyse, çağıran evre askıya alınır. Sonsuza kadar askıda kalır, çünkü başka hiçbir evre muteksin kilidini açamaz. Eğer muteks "hata kontrollü" türdeyse, pthread_mutex_lock EDEADLK hata koduyla hemen döner. Mutex "özyinelemeli" türdeyse, pthread_mutex_lock başarılı olur ve çağıran evrenin muteksi kaç kez kilitlediğini kaydederek hemen döner. Muteksi kilitsiz hale düşürmek için eşit sayıda pthread_mutex_unlock işlemi uygulanmalıdır.
int pthread_mutex_trylock
(pthread_mutex_t *muteks)
işlev
pthread_mutex_trylock işlevi pthread_mutex_lock ile aynı davranır, farklı olarak eğer muteks başka bir evre tarafından (veya "hızlı" muteks türünde çağıran evre tarafından) önceden kilitlenmişse, çağıran evreyi askıya almaz. Bunun yerine, pthread_mutex_trylock hemen EBUSY hata koduyla döner.
int pthread_mutex_timedlock
(pthread_mutex_t       *muteks,
 const struct timespec *mutlak_zaman)
işlev
pthread_mutex_timedlock işlevi pthread_mutex_lock işlevi ile aynıdır, fakat muteks başka bir evre tarafından kilitlendiğinde, sonsuza kadar askıya almaktansa mutlak_zaman ile belirtilen zamana erişildiğinde döner.
Bu işlev sadece standart ("zamanlı") ve "hata denetimli" mutekslerde kullanılabilir. Diğer bütün türler için pthread_mutex_lock gibi davranır.
Eğer muteks başarıyla kilitlendiyse, işlev sıfır döndürür. Eğer muteks kilitlenmeden mutlak_zaman süresi dolarsa, ETIMEDOUT döndürülür.
Bu işlev POSIX standartlarının POSIX.1d uyarlamasıyla tanıtılmıştır.
int pthread_mutex_unlock
(pthread_mutex_t *muteks)
işlev
pthread_mutex_unlock verilen muteksin kilidini açar. pthread_mutex_unlock işlevinin girişinde muteks kilitlenmiş ve çağıran evre tarafından sahiplenilmiş olarak kabul edilir. Eğer muteks "hızlı" türdeyse, pthread_mutex_unlock kilitsiz durumuna döndürür. Eğer "özyinelemeli" türdeyse, muteksin kilit sayısını azaltır (çağıran evre tarafından uygulanan pthread_mutex_lock işlemi sayısı), ve ancak bu sayı sıfıra ulaştığında muteks kilidi açılmış olur.
"Hata denetimli" mutekslerde, pthread_mutex_unlock aslında çalışma-anında muteksin kilitli olup olmadığını girişte kontol eder, ve o an pthread_mutex_unlock çağıranın kilitleyen evre olup olmadığına bakar. Eğer bu koşullar karşılanmadıysa, pthread_mutex_unlock işlevi EPERM döndürür, ve muteks değişmez. "Hızlı" ve "özyinelemeli" muteksler bu tür kontroller uygulamazlar, bu nedenle kilitli bir muteksin sahibinden başka bir evre tarafından kilidinin açılmasına izin verirler. Bu taşınabilir olmayan bir davranıştır ve güvenilemez.
int pthread_mutex_destroy
(pthread_mutex_t *muteks)
işlev
pthread_mutex_destroy bir muteks nesnesini, sahip olabileceği kaynakları serbest bırakarak yok eder. Girişte muteksin kilitlenmemiş olması gerekir. LinuxThreads gerçeklemesinde, muteks nesneleriyle hiçbir kaynak ilişkilendirilmemiştir, bu nedenle pthread_mutex_destroy aslında muteksin kilitli olup olmadığını kontrol etmekten başka bir şey yapmaz.
Eğer muteks bir evre tarafından kilitlendiyse, pthread_mutex_destroy işlevi EBUSY döndürür. Aksi takdirde 0 döndürür.
Eğer yukarıdaki işlevlerden herhangi biri (pthread_mutex_init dışında) hazırlanmamış bir mutekse uygulanırsa, sadece EINVAL döndürürler ve başka birşey yapmazlar.
Paylaşılan global bir x değişkeni bir muteks tarafından aşağıdaki gibi korunabilir:
int x;
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
x'e yapılan bütün erişim ve değişiklikler pthread_mutex_lock ve pthread_mutex_unlock arasına aşağıdaki gibi alınmalıdır.
pthread_mutex_lock(&mut);
/* x üzerindeki işlemler*/
pthread_mutex_unlock(&mut);
Muteks özellikleri muteksin oluşturulması sırasında pthread_mutex_init'e ikinci parametre olarak muteks özellik nesnesinin aktarılması ile belirtilebilirler. NULL aktarmak, bütün özellikleri öntanımlı değer verilmiş bir muteks özellik nesnesi aktarmakla eşdeğerdir.
int pthread_mutexattr_init
(pthread_mutexattr_t *öznitelik)
işlev
pthread_mutexattr_init işlevi öznitelik muteks özellik nesnesini hazırlar ve özelliklerini öntanımlı değerlerle doldurur.
Bu işlev her zaman 0 döndürür.
int pthread_mutexattr_destroy
(pthread_mutexattr_t *öznitelik)
işlev
pthread_mutexattr_destroy bir muteks özellik nesnesini yok eder, bu nesne tekrar hazırlanıncaya kadar tekrar kullanılmamalıdır. pthread_mutexattr_destroy LinuxThreads gerçeklemesinde birşey yapmaz.
Bu işlev her zaman 0 döndürür.
LinuxThreads sadece bir muteks özelliğini destekler: muteks türü. "hızlı" muteksler için PTHREAD_MUTEX_ADAPTIVE_NP, "özyinelemeli" muteksler için PTHREAD_MUTEX_RECURSIVE_NP, "zamanlı" muteksler için PTHREAD_MUTEX_TIMED_NP , veya "hata denetimli" muteksler için PTHREAD_MUTEX_ERRORCHECK_NP olabilir. NP ekinin de gösterdiği gibi, POSIX standardının taşınabilir olmayan bir oluşumudur ve taşınabilir yazılımlarda kullanılmamalıdır.
Muteks türü bir evre zaten sahip olduğu bir muteksi pthread_mutex_lock ile kilitlemeye çalıştığında ne olacağını belirler. Eğer muteks "hızlı" türdeyse, pthread_mutex_lock sadece çağıran evreyi sonsuza kadar askıya alır. Eğer muteks "hata denetimli" türdeyse, pthread_mutex_lock hemen EDEADLK hata koduyla döner. Eğer muteks "özyinelemeli" türdeyse, pthread_mutex_lock'a yapılan çağrı hemen bir başarı dönüş koduyla döner. Evrenin mutekse kaç kez sahip olduğu muteks içinde kayıtlanır. Muteksin kilitsiz duruma dönmesi için, sahip olan evre pthread_mutex_unlock işlevini aynı sayıda çağırmalıdır.
Varsayılan muteks türü PTHREAD_MUTEX_TIMED_NP olan "zamanlı"dır.
int pthread_mutexattr_settype
(pthread_mutexattr_t *öznitelik,
 int                  tür)
işlev
pthread_mutexattr_settype işlevi öznitelik içindeki muteks türü özelliğini tür ile belirtilen değere ayarlar.
Eğer tür PTHREAD_MUTEX_ADAPTIVE_NP, PTHREAD_MUTEX_RECURSIVE_NP, PTHREAD_MUTEX_TIMED_NP, veya PTHREAD_MUTEX_ERRORCHECK_NP değilse, bu işlev EINVAL döndürür ve öznitelik değerini değiştirmez.
Standart Unix98 tanıtıcıları olan PTHREAD_MUTEX_DEFAULT, PTHREAD_MUTEX_NORMAL, PTHREAD_MUTEX_RECURSIVE ve PTHREAD_MUTEX_ERRORCHECK değerlerine de izin verilmiştir.
int pthread_mutexattr_gettype
(const pthread_mutexattr_t *öznitelik,
 int                       *tür)
işlev
pthread_mutexattr_gettype işlevi öznitelik içindeki geçerli muteks türü özelliğini alır ve tür ile gösterilen yerde saklar.
Bu işlev her zaman 0 döndürür.
Önceki Üst Ana Başlık Sonraki
Temizlik İşleyicileri Başlangıç Koşul Değişkenleri
Bir Linux Kitaplığı Sayfası