Koşul Değişkenleri
Önceki POSIX Evreleri Sonraki
Koşul Değişkenleri
Bir koşul ("koşul değişkeni" yerine), evrelerin işletilmeyi paylaşılan veride bir karara varıncaya kadar askıya almasına olanak veren bir eşzamanlama aracıdır. Koşullar üzerindeki temel işlemler: koşula sinyal göndermek (Karar doğru çıkınca) ve başka bir evre koşula sinyal gönderene kadar evrenin işletilmesini askıya alarak koşul için beklemek.
Yarış koşulundan (race condition) kaçınmak için bir koşul değişkeni herzaman bir muteks ile ilişkilendirilmelidir. Öyle ki yarış koşulunda bir evre bir koşul değişkeni için beklemeye hazırlanırken başka bir evre ilk evre tam beklemeye başlayacakken koşula sinyal gönderir.
int pthread_cond_init
(pthread_cond_t           *koşul,
 pthread_condattr_t *koşul_özelliği)
işlev
pthread_cond_init işlevi koşul koşul değişkenini, koşul_özelliği içinde belirtilen koşul özelliklerini kullanarak ya da eğer koşul_özelliği NULL ise öntanımlı özellikleri kullanarak hazırlar. LinuxThreads gerçeklemesi koşullar için özellikleri desteklemez, bu yüzden koşul_özelliği parametresi dikkate alınmaz.
pthread_cond_t türündeki değişkenler de PTHREAD_COND_INITIALIZER sabitini kullanarak durağan olarak hazırlanabilirler.
Bu işlev her zaman 0 döndürür.
int pthread_cond_signal
(pthread_cond_t *koşul)
işlev
pthread_cond_signal işlevi koşul koşul değişkeni için bekleyen evrelerden birini yeniden başlatır. Eğer hiçbir evre koşul için beklemiyorsa, bir şey olmaz. Eğer koşul için birçok evre bekliyorsa, araların biri yeniden başlatılır.
Bu işlev her zaman 0 döndürür.
int pthread_cond_broadcast
(pthread_cond_t *koşul)
işlev
pthread_cond_broadcast işlevi koşul koşul değişkeni için bekleyen bütün evreleri yeniden başlatır. koşul için bekleyen hiç evre yoksa birşey olmaz.
Bu işlev her zaman 0 döndürür.
int pthread_cond_wait
(pthread_cond_t  *koşul,
 pthread_mutex_t *muteks)
işlev
pthread_cond_wait işlevi muteks'in kilidini atomik olarak açar (pthread_unlock_mutex gibi) ve koşul koşul değişkeninin sinyal alması için bekler. Evre işletimi askıya alınır ve koşul değişkeni sinyal alana kadar işlemci zamanı harcamaz. pthread_cond_wait girişinde, muteks çağıran evre tarafından kilitlenmelidir. Çağıran evreye geri dönmeden önce, pthread_cond_wait muteks'i tekrar elde eder (pthread_lock_mutex gibi).
Muteks kilidini açmak ve koşul değişkeni üzerine askıya almak atomik olarak gerçekleşir. Bu nedenle, eğer bütün evreler koşula sinyal göndermeden önce hep muteksi elde etseler, bu evrenin muteksi kilitlemesiyle koşul değişkeni için bekleyeceği zaman aralığında koşula sinyal gönderilemeyeceğini temin eder.
Bu işlev her zaman 0 döndürür.
int pthread_cond_timedwait
(pthread_cond_t        *koşul,
 pthread_mutex_t       *muteks,
 const struct timespec *mutlak_zaman)
işlev
pthread_cond_timedwait işlevi muteks kilidini atomik olarak açar ve pthread_cond_wait'in yaptığı gibi koşul için bekler, fakat aynı zamanda bekleme süresini sınırlar. Eğer koşul mutlak_zaman süresinden önce sinyal almadıysa, muteks muteksi tekrar elde edilir ve pthread_cond_timedwait ETIMEDOUT hata kodunu döndürür. Bekleme de bir sinyal ile kesilebilir; bu durumda pthread_cond_timedwait işlevi EINTR döndürür.
mutlak_zaman parametresi, time ve gettimeofday ile aynı kökende kesin bir süre belirler: mutlak_zaman için 0 değeri 00:00:00 GMT, January 1, 1970 anlamına gelir.
int pthread_cond_destroy
(pthread_cond_t *koşul)
işlev
pthread_cond_destroy işlevi koşul koşul değişkenini sahip olabileceği kaynakları serbest bırakarak yok eder. Eğer herhangi bir evre koşul değişkeni için bekliyorsa, pthread_cond_destroy koşul koşulunu değiştirmeden bırakır ve EBUSY döndürür. Aksi takdirde 0 döndürür ve koşul tekrar hazırlanana kadar kullanılmamalıdır.
LinuxThreads gerçeklemesinde, koşul değişkenleriyle hiçbir kaynak ilişkilendirilmemiştir, bu yüzden pthread_cond_destroy aslında hiçbir şey yapmaz.
pthread_cond_wait ve pthread_cond_timedwait iptal noktalarıdır. Eğer bir evre bu işlevlerden biri tarafından askıya alındığında iptal edildiyse, evre çalışmaya geri döner, muteks ile belirtilen muteksi tekrar kilitler ve son olarak iptali işletir. Sonuç olarak, temizlik işleyicileri muteks'in çağrıldığında kilitli olduğuna emin olurlar.
Bir sinyal işleyicisinden koşul değişken işlevlerinin çağrılması güvenli değildir. Özellikle, bir sinyal işleyicisinden pthread_cond_signal veya pthread_cond_broadcast çağırmak çağıran evreyi kısır döngüye sokabilir.
mut muteksi tarafından korunan, paylaşılan iki x ve y değişkeni ve ne zaman x y'den büyük olsa sinyal alan bir cond koşul değişkeni düşünün.
int x,y;
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
x y'den büyük olana kadar beklemek aşağıdaki gibi yapılır:
pthread_mutex_lock(&mut);
while (x <= y) {
        pthread_cond_wait(&cond, &mut);
}
/* x ve y üzerinde işle*/
pthread_mutex_unlock(&mut);
x'in y'den büyük olmasına neden olabilecek x ve y üzerindeki değişiklikler gerektiğinde koşula sinyal göndermeli:
pthread_mutex_lock(&mut);
/*  x ve y'yi değiştir*/
if (x > y) pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mut);
Eğer en çok bir evrenin uyanması gerektiği kanıtlanabilirse (örneğin, x ve y üzerinden haberleşen sadece iki evre varsa), pthread_cond_signal işlevi pthread_cond_broadcast'in daha verimli bir alternatifi olarak kullanılabilir. Şüpheliyseniz pthread_cond_broadcast kullanın.
x'in y'den büyük oluncaya kadar 5 saniye beklenmesi için:
struct timeval now;
struct timespec timeout;
int retcode;

pthread_mutex_lock(&mut);
gettimeofday(&now);
timeout.tv_sec = now.tv_sec + 5;
timeout.tv_nsec = now.tv_usec * 1000;
retcode = 0;
while (x <= y && retcode != ETIMEDOUT) {
        retcode = pthread_cond_timedwait(&cond, &mut, &timeout);
}
if (retcode == ETIMEDOUT) {
        /* zaman aşımı oluştu */
} else {
        /* x ve y üzerinde işlem yap*/
}
pthread_mutex_unlock(&mut);
Koşul özellikleri,pthread_cond_init işlevinin ikinci argümanı olarak koşul özellik nesnesi geçirilerek, koşul oluşturulması esnasında belirtilebilir. NULL geçirmek, bütün özellikleri öntanımlı değer verilmiş bir koşul özellik nesnesi geçirmekle eşdeğerdir.
LinuxThreads gerçeklemesi koşullar için hiçbir özellik desteklememektedir. Koşul özellikleriyle ilgili işlevler sadece POSIX standardıyla uyum için içerilmektedir.
int pthread_condattr_init
(pthread_condattr_t *öznitelik)
işlev
int pthread_condattr_destroy
(pthread_condattr_t *öznitelik)
işlev
pthread_condattr_init işlevi öznitelik koşul özellik nesnesini hazırlar ve özelliklerini öntanımlı değerlerle doldurur. pthread_condattr_destroy işlevi ise öznitelik koşul özellik nesnesini yok eder.
Her iki işlev de LinuxThreads gerçeklemesinde bir şey yapmaz.
pthread_condattr_init ve pthread_condattr_destroy herzaman 0 döndürr.
Önceki Üst Ana Başlık Sonraki
Muteksler Başlangıç POSIX Semaforları
Bir Linux Kitaplığı Sayfası