POSIX Timer API
Önceki bölümde değindiğimiz geleneksel timer yapılarının çok önemli bir handikapı vardı. En gelişmişi olan interval timer mekanizmasında bile aynı anda en fazla 3 farklı tipte timer işletmek mümkündü. Herhangi bir tipte yeni bir timer kurulduğunda, zaman olduğunda uygulamayı aynı yöntemle (aynı sinyalle) haberdar ettiğinden birbirinden bağımsız onlarca timer gerektiren senaryolar için verimli bir çözüm üretmek mümkün değildi.
Bu bölümde POSIX tarafından standardize edilen gelişmiş timer kullanımına değineceğiz. Bir POSIX timer'ın oluşturulması, süresinin ayarlanması ve artık ihtiyaç kalmadığı anda yok edilmesinden oluşan temelde 3 aşamalı bir yaşam döngüsü bulunur.
Not: POSIX timer kullanan uygulamalar derlenirken
-lrt
ile POSIX.1b Realtime Extensions kütüphanesine de linklenmelidir.
Oluşturma: timer_create
timer_create
Timer işlemlerinde timer_t
tipindeki handle, aşağıda prototipi bulunan timer_create()
fonksiyonu ile elde edilmelidir.
İlk parametre ile kullanılacak clock tipi belirtilir.
Clock Tipi
Açıklama
CLOCK_REALTIME
Gerçek zamanda geçen süre cinsinden zaman hesaplanır. Bu değer sistem saatinin ileri veya geri alınmasından etkilenir.
CLOCK_MONOTONIC
Sistem açılışında sıfırlanan, saat ayarlamalarından etkilenmeyen güvenilir MONOTONIC zaman değeri üzerinden hesaplanır.
CLOCK_PROCESS_CPUTIME_ID
Uygulamanın tüm thread'lerinin kullanıcı kipi ve çekirdek kipinde harcadığı toplam süre üzerinden hesaplanır.
CLOCK_THREAD_CPUTIME_ID
Uygulama içerisinde sadece timer oluşturma isteğini gönderen thread için kullanıcı kipi ve çekirdek kipinde harcanan süre toplamı üzerinden hesaplanır.
Fonksiyonun 2. parametresi struct sigevent
türünde olup prototipi aşağıdaki gibidir:
Yapı içerisinde yer alan sigev_notify
elemanı, timer zamanı dolduğunda uygulamanın nasıl haberdar edileceğini kontrol etmemizi sağlar. Kullanılabilecek sabitler aşağıdaki gibidir:
sigev_notify
Açıklama
SIGEV_NONE
Timer sona erdiğinde uygulamaya herhangi bir bildirimde bulunulmaz
SIGEV_SIGNAL
Timer sona erdiğinde uygulamaya sigev_signo
alanında girilen tipte sinyal gönderilir. Sinyal callback fonksiyonunun si_value
değerine, bu yapı ile belirtilen union sigev_value
alanıyla tanımlanan parametre geçirilir.
SIGEV_THREAD
Timer sona erdiğinde işletim sistemi yeni bir thread oluşturur. Thread içerisinde sigev_notify_function
fonksiyonu çağrılır. Fonksiyona parametre olarak union sigev_value
alanında belirtilen değer geçirilir. Ek olarak oluşturulacak threadin özellikleri belirlenmek istenirse pthread_attr_t
tipindeki sigev_notify_attributes
alanı kullanılabilir.
Oluşturulan POSIX timer için sinyalle uyandırılma seçildi ise sigev_signo
alanında verilen sinyalin callback fonksiyonu standart sinyal işleme yöntemleriyle tanımlanmalıdır. Bu noktada dikkat edilecek ek husus, struct sigaction
veri yapısı ile callback tanımlanırken sa_flags
elemanının değerini SA_SIGINFO sabitine eşitlemektir.
Bu şekilde ilgili callback fonksiyonu sinyal nedeniyle çağrıldığında geleneksel sinyal işleme yöntemindeki gibi sadece sinyal numarasını parametre alan bir fonksiyon çağırmaz, bunun yerine aşağıdaki fonksiyon prototipinde bir çağrıda bulunur:
Bu sayede siginfo_t
ile gelen elemanın içerisinden, timer oluşturulma sırasında ayarlanan sigev_value
geri alınabilir. Asenkron çalışma sistematiği için bu şekildeki bir kullanım çoğu zaman zorunlu olacaktır.
Üçüncü argüman olan genel amaçlı
context
pointer verisi timer mekanizmasında kullanılmaz. Kullanım senaryosunu incelemek içingetcontext()
fonksiyonuna bakabilirsiniz: http://manpages.org/getcontext/3
Ayarlama: timer_settime
timer_settime
Timer oluşturup timer_t
türünde bir handle elde ettikten sonra, aşağıda prototipi yer alan timer_settime()
fonksiyonuyla interval timer sürecine benzer şekilde değerler ayarlanır.
Interval timer kullanımından farkı it_interval
ve it_value
için struct timeval
yerine, nanosaniye seviyesinde değer girilebilmesine imkan veren struct timespec
tipi kullanılmaktadır. Benzer şekilde it_value
elemanında ilgili timer'ın ilk çalıştığındaki kullanacağı süre değeri, it_interval
elemanında ise sonraki seferlerde periyodik olarak kullanılacak değer yer alır.
İkinci parametre olan flags
argümanı normalde 0 olarak kullanılır. Bu durumda öntanımlı davranış, kullanılan clock tipine göre göreceli şekilde it_value
alanındaki timer'ın ilk çalışmasındaki süre değeri dikkate alınır. Örnek olarak it_value
bölümünde 5 saniyelik bir zaman dilimi tanımlanmışsa, kullanılan clock tipine göre göreceli olarak timer ayarlama zamanından 5 saniye sonra ilk uyandırma gerçekleşir.
Bununla birlikte bazen ilk uyandırma işleminin göreceli olarak değil de belirli bir anda yaptırılması istenebilir. Örnek olarak tam olarak bir sonraki saat başında ilk olarak uyandırılmak, sonra da saniyede bir periyodik uyandırılmak istenebilir. Bu durumda flags
bölümünde TIMER_ABSTIME sabiti kullanılabilir.
Verilen bir timer_t
handle üzerinden bir sonraki uyandırma zamanına ne kadar kaldığı da timer_gettime()
fonksiyonu alınabilmektedir.
Yok Etme: timer_delete
timer_delete
Kullanılmayan timer değerler, prototipi aşağıda belirtilen timer_delete()
fonksiyonuyla yok edilir ve harcadığı sistem kaynakları geri verilir:
Örnek Uygulama
Aşağıdaki uygulamayı posix.c
adıyla kaydedip ardından derleyip çalıştıralım.
Derleyip çalıştırdığımızda beklediğimiz gibi 2 farklı timer, kendileriyle ilgili özel veri yapısınının adresini de taşıyarak callback fonksiyonunu çağırmaktadır.
Last updated
Was this helpful?