2014-05-09 24 views
6

Saniyede 1000 kez kod çalıştırmam gerekiyor. ben böyle bir şey yapmak istiyorum: Ben bu çalıştığımda, sadece konsolda ve programım çıkışlarında "Kullanıcı sinyalini 1 tanımlanan" olsun Zamanlanmış döngü nasıl uygulanır?

// Create timer 
timer_t timerid; 
struct sigevent sev; 

sev.sigev_notify = SIGEV_SIGNAL; 
sev.sigev_signo = SIGUSR1; 

if (timer_create(CLOCK_REALTIME, &sev, &timerid)) 
{ 
perror("timer_create"); 
exit(1); 
} 

// Every one mSec (10^6 nsec) 
struct itimerspec its; 
its.it_value.tv_sec = 0; 
its.it_value.tv_nsec = 1000000; 
its.it_interval.tv_sec = 0; 
its.it_interval.tv_nsec = 1000000; 
if (timer_settime(timerid, 0, &its, NULL)) 
{ 
perror("timer_settime"); 
exit(1); 
} 

// Create mask to wait for SIGUSR1 
sigset_t set; 
sigemptyset(&set); 
sigaddset(&set, SIGUSR1); 

while (1) 
{ 
int sig; 

// Wait for the timer: Do this loop once per millisecond 
sigwait(&set, &sig); 

    (do something) 
} 

gibi

set up interval timer 
while (1) 
{ 
    wait for timer 
    do something 
} 

girişimim görünüyor. Bu şaşırtıcı değildir, çünkü bu sinyal için varsayılan eylemdir. SIG_IGN sinyalini sigaction (2) kullanarak ayarladıysam, asla (bir şey yap) alamam.

İmzalı bir şey yapmam gerektiğini varsayalım (2), fakat "sinyali ilet" için bir seçenek göremiyorum. Sinyali göz ardı etmek ya da varsayılan eylemi yapmak ya da bir işlevi çağırmak istemiyorum. Amacımı gerçekleştirmenin en iyi yolu nedir?

Veya sadece vazgeçmek ve koyabilirsiniz benim

Edit :-) bir işlevde (bir şey yapmak): Ben timerfd fikri hayata ve işe yarıyor gibi görünüyor. Bir sonraki hatayı ...

+0

Neden sadece uygun aralık için 'nanosleep' değil? Eylemin yürütülmesi gerektiğinde ve o anki saatte bir sonraki zaman damgasına göre aralığı kendiniz hesaplamanız gerektiğini unutmayın. (Yinelemeler arasında her zaman 1 ms beklerseniz, saniyede 1000 iterasyon uygularsınız, tam olarak kaç kez "bir şeyler yap" a bağlıdır.) – user4815162342

+0

SIG_IGN'ın yanında oldukça büyük bir dizi olası eylem vardır. –

+0

@ n.m "SIG_IGN'ın yanında oldukça büyük bir dizi olası eylem var." Http://man7.org/linux/man-pages/man2/sigaction.2.html'den alıntı: sa_handler, signum ile ilişkilendirilecek eylemi belirtir ve varsayılan eylem için SIG_DFL, bu sinyali yok saymak için SIG_IGN olabilir veya Bir sinyal işleme fonksiyonuna bir işaretçi. Başka hangi seçenekler mevcut? – rich

cevap

4

Sorunuzu embedded-linux ile etiketlediğiniz için, taşınabilirliğin bir sorun olmadığını varsayalım. Bu durumda timerfd'a bir göz atmak isteyebilirsiniz. Zamanlayıcı etkinliklerinizi almak için select(2)/poll(2)'u kullanmanıza izin verecektir. Ayrıca, aralık zamanlayıcısını dosya tanıtıcıları gibi diğer olay kaynakları ile birleştirmeyi de kolaylaştıracaktır.

+0

+ 1. Bu sayede programınız, bir şey kütüphanesi için SIGUSR1 kullanan bir kütüphaneye bağlansanız bile çalışmaya devam edecektir. –

0

n.m. tarafından önerilen şekilde gerçek bir sinyal işleyicisi ayarlamanız gerektiğini düşünüyorum. Linux sürümünüz için man sigaction'a bakın. Sinyal işleyicide do_something numaranızı arayabilir (ve program sonlandırma için başka bir şey bekleyebilir) ya da yalnızca işleyiciye geri dönebilir ve sizi sigwait mantığında tutabilirsiniz.