- 論壇徽章:
- 0
|
精確定時(shí)器設(shè)置《精通Unix下C語(yǔ)言編程與項(xiàng)目實(shí)踐》之六。
10.5.2 精通定時(shí)器設(shè)置
函數(shù)alarm設(shè)置的定時(shí)器只能精確到秒,而以下函數(shù)理論上可以精確到微妙:
#include
#include
int getitimer(int which, struct itimerval *value);
int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);
函數(shù)setitimer可以提供三種定時(shí)器,它們相互獨(dú)立,任意一個(gè)定時(shí)完成都將發(fā)送定時(shí)信號(hào)到進(jìn)程,并且自動(dòng)重新計(jì)時(shí)。參數(shù)which確定了定時(shí)器的類(lèi)型,如表10-6所示:
表10-6 參數(shù)which與定時(shí)器類(lèi)型
取值
含義
信號(hào)發(fā)送
ITIMER_REAL
定時(shí)真實(shí)時(shí)間,與alarm類(lèi)型相同。
SIGALRM
ITIMER_VIRT
定時(shí)進(jìn)程在用戶(hù)態(tài)下的實(shí)際執(zhí)行時(shí)間。
SIGVTALRM
ITIMER_PROF
定時(shí)進(jìn)程在用戶(hù)態(tài)和核心態(tài)下的實(shí)際執(zhí)行時(shí)間。
SIGPROF
這三種定時(shí)器定時(shí)完成時(shí)給進(jìn)程發(fā)送的信號(hào)各不相同,其中ITIMER_REAL類(lèi)定時(shí)器發(fā)送SIGALRM信號(hào),ITIMER_VIRT類(lèi)定時(shí)器發(fā)送SIGVTALRM信號(hào),ITIMER_REAL類(lèi)定時(shí)器發(fā)送SIGPROF信號(hào)。
函數(shù)alarm本質(zhì)上設(shè)置的是低精確、非重載的ITIMER_REAL類(lèi)定時(shí)器,它只能精確到秒,并且每次設(shè)置只能產(chǎn)生一次定時(shí)。函數(shù)
setitimer設(shè)置的定時(shí)器則不同,它們不但可以計(jì)時(shí)到微妙(理論上),還能自動(dòng)循環(huán)定時(shí)。在一個(gè)Unix進(jìn)程中,不能同時(shí)使用alarm和
ITIMER_REAL類(lèi)定時(shí)器。
結(jié)構(gòu)itimerval描述了定時(shí)器的組成:
struct itimerval
{
struct tim. it_interval; /* 下次定時(shí)取值 */
struct tim. it_value; /* 本次定時(shí)設(shè)置值 */
}
結(jié)構(gòu)tim.描述了一個(gè)精確到微妙的時(shí)間:
struct tim.
{
long tv_sec; /* 秒(1000000微秒) */
long tv_usec; /* 微妙 */
}
函數(shù)setitimer設(shè)置一個(gè)定時(shí)器,參數(shù)value指向一個(gè)itimerval結(jié)構(gòu),該結(jié)構(gòu)決定了設(shè)置的定時(shí)器信息,結(jié)構(gòu)成員it_value指定
首次定時(shí)的時(shí)間,結(jié)構(gòu)成員it_interval指定下次定時(shí)的時(shí)間。定時(shí)器工作時(shí),先將it_value的時(shí)間值減到0,發(fā)送一個(gè)信號(hào),再將
it_value賦值為it_interval的值,重新開(kāi)始定時(shí),如此反復(fù)。如果it_value值被設(shè)置為0,則定時(shí)器停止定時(shí);如果
it_value值不為0但it_interval值為0,則定時(shí)器在一次定時(shí)后終止。
函數(shù)setitimer調(diào)用成功時(shí)返回0,否則返回-1,參數(shù)ovalue如果不為空,返回上次的定時(shí)器狀態(tài)。
函數(shù)getitimer獲取當(dāng)前的定時(shí)器狀態(tài),整型參數(shù)which指定了讀取的定時(shí)器類(lèi)型,參數(shù)value返回定時(shí)器狀態(tài)。函數(shù)調(diào)用成功返回0,否則返回-1。
例1. 設(shè)置一個(gè)定時(shí)器,每2.5秒產(chǎn)生一個(gè)SIGALRM信號(hào)。
答:將itimerval結(jié)構(gòu)的成員it_interval和成員it_value均賦值為2.5秒即可:
struct itimerval value;
value.it_value.tv_sec=2;
value.it_value.tv_usec=500000;
value.it_interval.tv_sec=2;
value.it_interval.tv_usec=500000;
setitimer(ITIMER_REAL, &value, NULL);
函數(shù)setitimer設(shè)置的定時(shí)器可以重復(fù)定時(shí),無(wú)需多次調(diào)用。
例2. 設(shè)置一個(gè)定時(shí)器,進(jìn)程在用戶(hù)態(tài)下執(zhí)行1秒鐘后發(fā)出首次信號(hào),以后進(jìn)程每在用戶(hù)態(tài)下執(zhí)行3秒鐘,發(fā)送一個(gè)信號(hào)。
答:將itimerval結(jié)構(gòu)的成員it_value均賦值為1秒,成員it_interval賦值為3秒即可:
struct itimerval value;
value.it_value.tv_sec=1;
value.it_value.tv_usec=0;
value.it_interval.tv_sec=3;
value.it_interval.tv_usec=0;
setitimer(ITIMER_VIRT, &value, NULL);
例3. 取消一個(gè)ITIMER_PROF類(lèi)定時(shí)器。
答:將itimerval結(jié)構(gòu)的成員it_value均賦值為0秒即可:
struct itimerval value;
value.it_value.tv_sec=1;
value.it_value.tv_usec=0;
setitimer(ITIMER_PROF, &value, NULL);
例4. 設(shè)置一個(gè)定時(shí)1.5秒的真實(shí)時(shí)間定時(shí)器,它僅發(fā)送一次信號(hào)就自動(dòng)取消。
答:將itimerval結(jié)構(gòu)的成員it_value均賦值為1.5秒,成員it_interval賦值為0秒即可:
struct itimerval value;
value.it_value.tv_sec=1;
value.it_value.tv_usec=500000;
value.it_interval.tv_sec=0;
value.it_interval.tv_usec=0;
setitimer(ITIMER_REAL, &value, NULL);
精確定時(shí)器實(shí)例
本處設(shè)計(jì)了一個(gè)精確定時(shí)器的例子,進(jìn)程每隔1.5秒數(shù)發(fā)送定時(shí)信號(hào)SIGPROF,在接收到信號(hào)時(shí)將打印定時(shí)的次數(shù),用戶(hù)可以鍵入CTRL_C或DELETE結(jié)束程序,如代碼10-11所示:
代碼10-11 精確定時(shí)器實(shí)例(節(jié)自/code/chapter10/time4.c)
#include
#include
#include
#include
#include
int n = 0;
void timefunc(int sig) /* 定時(shí)事件代碼 */
{
fprintf(stderr, "ITIMER_PROF[%d]n", n++);
signal(SIGPROF, timefunc); /* 捕獲定時(shí)信號(hào) */
}
void main()
{
struct itimerval value;
value.it_value.tv_sec=1; /* 定時(shí)1.5秒 */
value.it_value.tv_usec=500000;
value.it_interval.tv_sec=1; /* 定時(shí)1.5秒 */
value.it_interval.tv_usec=500000;
signal(SIGPROF, timefunc); /* 捕獲定時(shí)信號(hào) */
setitimer(ITIMER_PROF, &value, NULL); /* 定時(shí)開(kāi)始 */
while (1);
}
編譯和運(yùn)行代碼10-11:
# make time4
cc -O -o time4 time4.c
# ./time4
ITIMER_PROF[0]
ITIMER_PROF[1]
ITIMER_PROF[2]
ITIMER_PROF[3]
本文來(lái)自ChinaUnix博客,如果查看原文請(qǐng)點(diǎn):http://blog.chinaunix.net/u1/39518/showart_1975961.html |
|