Zamanlayıcı mekanizmaları, önceden belirlenmiş bir süre geçtiğinde bir uygulamayı bilgilendirmek için OS çekirdeğini programlamanıza izin verir. Bunları genellikle iki parça bilgi sağlayarak kullanırsınız. Öncelikle, bildirimde bulunmadan önce zamanlayıcının ne kadar zaman alacağını belirtmeniz gerekir. İkinci olarak, bu bildirim gerçekleştiğinde harekete geçecek bir geri arama işlevi hazırlamanız gerekir.

Zamanlayıcılara Geleneksel Yaklaşım

Linux ve Unix tabanlı sistemlerdeki zamanlayıcı mekanizmaları, çeşitli ihtiyaçlara hizmet edecek şekilde gelişmiştir. Farklı yaklaşımlar, farklı sorun türlerini çözmenize yardımcı olabilir. Ancak, genellikle uygulamanın ilk sürümünü görürsünüz. alarm() mekanizma hala kullanılıyor.

Alarm işlevi, bir zamanlayıcı kullanmanın en basit yoludur; işte prototipi:

imzasızintalarm(imzasızint saniye);

Bu yöntemi kullanarak, zamanı yalnızca tam saniye olarak belirtebilirsiniz. Süre dolduğunda, işletim sistemi SİGALRM uygulamanıza sinyal verin. Uygulamanızda zamanlayıcının sona ermesini işlemek için bir geri arama işlevi de tanımlamanız gerekir.

instagram viewer

İşte bir sinyal işleyici işlevine bir örnek:

#Dahil etmek
#Dahil etmek
#Dahil etmek
#Dahil etmek

geçersiztimer_callback(int işaret)
{
zaman_t şimdi = zaman(HÜKÜMSÜZ);
baskı("Sinyal %d, %li'de yakalandı", signum, şimdi);
}

intana()
{
sinyal (SIGALRM, timer_callback);
alarm(1);
uyumak(3);
dönüş0;
}

Bu kod bir yükseltir SİGALRM sonra sinyal 1 ikinci. Zamanlayıcı gecikmesini beş saniyeye çıkarmak istiyorsanız, aramanız yeterlidir. alarm (5) yerine. Zamanlayıcıyı durdurmak için 0 değerini iletin: alarm (0).

Süre dolduğunda, kullandığınız zamanlayıcı periyodik olarak yeniden başlamaz. Örneğin, bir saniye daha geciktirmek istiyorsanız, başka bir çağrı ile mekanizmayı yeniden başlatmalısınız. alarm().

Kullanım kolaylığına rağmen, bu yöntemin bazı dezavantajları vardır:

  • Bir seferde yalnızca bir zamanlayıcı.
  • Periyodik zamanlayıcı desteği yok.
  • Süreyi yalnızca tam saniyenin katları olarak verebilirsiniz.
  • Bir zamanlayıcıda ne kadar zaman kaldığını bilmenin yolu yok.

Yukarıda verilen örnek kodu şu şekilde kaydedin: alarm.c. Ne zaman derleyip çalıştırıyorsun o, program arayacak timer_callback bir saniye sonra işlev. Daha sonra kalan iki saniye için bekleyecektir. uyku (3) satırını seçin, ardından sonlandırın.

$ gcc -o alarm alarmı.c
$ zaman ./alarm
Sinyal 14, 1653490465'te yakalandı
gerçek 0m1.004s
kullanıcı 0m0.000s
sistem 0m0.003s

time komutunun kullanılmasının nedeni ise saatleri görebilmektir. Ama sonuca bakarsanız toplam koşu süresi üç saniye değil. Bunun nedeni SİGALRM gelen sinyal alarm (1) ilk saniye dolduğunda, sistem çağrısı uyku (3) işlevi çalışıyor. Bu sinyal geldiğinde, başlatılan sistem çağrısını keser. uyku (3).

Aralıklı Zamanlayıcı Kullanmak

Aralık zamanlayıcı mekanizması ilk olarak 4.2 BSD sürümünde mevcuttu. Daha sonraydı POSIX tarafından standartlaştırılmış. Geleneksel olana göre ana avantajları alarm() tabanlı zamanlayıcı yöntemi şunlardır:

  • Mikrosaniye çözünürlük sağlar.
  • Üç farklı mod üzerinden zaman ölçümünün daha detaylı kontrol edilmesini sağlar.
  • Bir kez ayarlayıp periyodik olarak çalışmasını sağlamak mümkündür.
  • Herhangi bir anda ne kadar süredir mevcut olduğunu bulmak mümkündür.

Aralık zamanlayıcı işlemleri için kullanılan fonksiyon prototipleri aşağıdaki gibidir:

#Dahil etmek

intsetitimer(int Hangi, const struct itimerval *yeniDeğer, struct itimerval *eskiDeğer);
intgetimer(int hangi, yapı itimerval *değer);

yapızaman aralığı
{
yapızaman aralığıoAralık;// sonraki değer
yapızaman aralığıitValue;// Mevcut değer
};

yapızaman aralığı
{
uzun tv_sec;
uzun tv_usec;
};

Bir aralık zamanlayıcı ayarlamak istiyorsanız, zaman aralığı yapı. İkinci argüman olarak bu yapıyı kullanarak bir değer iletmeniz gerekecek. zamanlayıcıyı Kur işlev.

Örneğin, uygulamanızı 1 saniye ve ardından her 300 milisaniyede bir bilgilendirecek bir interval timer şu şekilde kurulabilir:

yapızaman aralığıyeniZamanlayıcı;
yapızaman aralığıeski zaman;

newTimer.itValue.tv_sec = 1;
newTimer.itValue.tv_usec = 0;

newTimer.itInterval.tv_sec = 0;
newTimer.itInterval.tv_usec = 300 * 1000;

setitimer (ITIMER_REAL, &newTimer, &oldTimer);

Yeni değerler ayarlanmadan önce aktif olan bir interval timer varsa değerleri değişken adresine transfer edilir. zaman aralığı işlevin üçüncü parametresine verilen tür.

Aralıklı zamanlayıcı mekanizması ile üç farklı türde zamanlayıcı kurabilirsiniz. İlk parametrede zamanlayıcı türünü belirtin setitimer():

Zamanlayıcı Türü sinyal Açıklama
ITIMER_REAL SİGALRM Uygulamanın harcadığı zamandan bağımsız, toplam geçen süre üzerinden hesaplanır.
ITIMER_VIRTUAL SIGVTALRM Uygulamanın yalnızca kullanıcı modunda çalıştığı süre üzerinden hesaplanır.
ITIMER_PROF SIGPROF Uygulamanın hem kullanıcı hem de sistem modlarında harcadığı zamanın toplamı üzerinden hesaplanır.

Bu tablodan görebilirsiniz ki, ITIMER_REAL tip bir gönderir SİGALRM sinyal, tıpkı alarm() işlev.

Aralıklı bir zamanlayıcı kullanma ve alarm() aynı uygulamada kafa karıştırıcı olacaktır. Bununla birlikte kalan süreyi ikinci kez kontrol edebilirsiniz. gettimer(), onları aynı anda kullanmak mantıklı değil.

Burada, sinyal işleyici işlevini aşağıdaki komutla tanımlamanın bir örneği verilmiştir: hata ayıklama başlığı:

#Dahil etmek
#Dahil etmek
#Dahil etmek
#Dahil etmek
#Dahil etmek
#Dahil etmek
#Dahil etmek
#Dahil etmek "./debug.h"

geçersiztimer_callback(int işaret)
{
yapızaman aralığışimdi;
gettimeofday(&şimdi, HÜKÜMSÜZ);
baskı("Sinyal %d, %li.%'de yakalandı03lben ", signum, now.tv_sec, now.tv_usec / 1000);
}

intana()
{
imzasızint kalan = 3;

yapızaman aralığınew_timer;
yapızaman aralığıeski zaman;

new_timer.it_value.tv_sec = 1;
new_timer.it_value.tv_usec = 0;
new_timer.it_interval.tv_sec = 0;
new_timer.it_interval.tv_usec = 300 * 1000;

setitimer (ITIMER_REAL, &new_timer, &old_timer);
sinyal (SIGALRM, timer_callback);

süre (uyku (kalan) != 0)
{
eğer (errno == EINTR)
debugf("uyku sinyalle kesildi");
başka
errorf("uyku hatası %s", strerror (errno));
}

dönüş0;
}

Yukarıdaki kod kullanır uyumak() üç saniye bekleme işlevi. Bu süre boyunca, önce bir saniye, ardından 300 milisaniyelik aralıklarla bir aralık sayacı çalışır.

Daha iyi anlamak için örnek kodu kaydedin ve adla birlikte derleyin. aralık.c:

$ gcc -o aralık aralığı.c
$ zaman ./aralık
Sinyal 14, 1653493614.325'te yakalandı
hata ayıklama: sinyal tarafından kesintiye uğrayan uyku (ana aralık.c: 36)
Sinyal 14, 1653493614.625'te yakalandı
hata ayıklama: sinyal tarafından kesintiye uğrayan uyku (ana aralık.c: 36)
Sinyal 14, 1653493614,925'te yakalandı
hata ayıklama: sinyal tarafından kesintiye uğrayan uyku (ana aralık.c: 36)
Sinyal 14, 1653493615.225'te yakalandı
hata ayıklama: sinyal tarafından kesintiye uğrayan uyku (ana aralık.c: 36)
Sinyal 14, 1653493615.525'te yakalandı
...

Zamanlayıcı çalıştıktan sonra çıktıdan da görebileceğiniz gibi, her 300 milisaniyede bir geri arama işlevini çağırır.

Ancak biraz daha bekledikten sonra uygulamanın sonlanmadığını fark edeceksiniz. Her 300 milisaniyede bir geri arama işlevini çalıştırmaya devam eder. Aralık değerini milisaniye cinsinden artırırsanız uygulamanın sonlandırıldığını göreceksiniz. Bunun nedeni, ürünün kullanım alanıdır. uyumak() işlev.

Linux'ta Zamanlayıcı Kullanmanın Önemi

Özellikle gerçek zamanlı uygulamalar için zamanlayıcı mekanizması büyük önem taşımaktadır. Bu aynı zamanda performans optimizasyonları için kullanılan bir çözümdür. Uygulamanızda çalışma süresini veya gecikmeyi ölçmek için bile kullanabilirsiniz. Geçen zaman ve zaman geçiş olaylarını takip etmek için zamanlayıcı mekanizmalarını kullanmak önemlidir.

Linux'ta Kaynaktan Yazılım Nasıl Derlenir ve Kurulur

Sonrakini Oku

PaylaşmakCıvıldamakPaylaşmakE-posta

İlgili konular

  • Programlama
  • Programlama
  • Linux İpuçları

Yazar hakkında

Fatih Küçükkarakurt (10 Makale Yayınlandı)

Matematik ve teknolojinin hayranı olan bir mühendis ve yazılım geliştiricisi. Bilgisayarları, matematiği ve fiziği her zaman sevmiştir. Oyun motoru projelerinin yanı sıra makine öğrenimi, yapay sinir ağları ve lineer cebir kütüphaneleri geliştirmiştir. Ayrıca makine öğrenmesi ve lineer matrisler üzerinde çalışmalarını sürdürmektedir.

Fatih Küçükkarakurt'dan Daha Fazla

Haber bültenimize abone ol

Teknik ipuçları, incelemeler, ücretsiz e-kitaplar ve özel fırsatlar için bültenimize katılın!

Abone olmak için buraya tıklayın