Linux间隔定时器的使用 探索一

2011年1月17日

之前看《高级Unix编程》说有基本定时器与高级定时器之分

好像基本定时器不符合我的要求,那么就先来个高级的吧。

写个代码看看会有什么发生:

2011年1月18日

看下timer_create函数

int t1;
timer_t tm_id;//timer_t其实是个long型
t1 = timer_create(CLOCK_REALTIME, NULL, &tm_id);
cout << "timer_create return " << t1 << endl;
cout << "tm_id" << tm_id << endl;

int t2;
timer_t tm_id2;//timer_t其实是个long型
t2 = timer_create(CLOCK_REALTIME, NULL, &tm_id2);
cout << "timer_create return " << t2 << endl;
cout << "tm_id" << tm_id2 << endl;

可看到输出的第一个time_id是0,第二个是1,其实就是用数字标识timerID啦。

2011年1月21日

今天终于试验出了个timer的用法:

下面是代码:

#include #include #include using std::cout;
using std::endl;

void alrm_handler(int i)
{
    printf("timer interrupt %d/n",i);
    time_t tm_show;
    time(&tm_show);
    cout << "settime : " << (long)tm_show << "s " << endl;
}

int main()
{

    int t1;
    timer_t tm_id;//timer_t其?实?是?个?long型?
    t1 = timer_create(CLOCK_REALTIME, NULL, &tm_id);
    cout << "timer_create return " << t1 << endl;
    cout << "tm_id" << tm_id << endl;

    int t2;
    timer_t tm_id2;//timer_t其?实?是?个?long型?
    t2 = timer_create(CLOCK_REALTIME, NULL, &tm_id2);
    cout << "timer_create return " << t2 << endl;
    cout << "tm_id" << tm_id2 << endl;

    cout << "set the timer "<< tm_id << ": 5s" << endl;
    cout << "set timer " << tm_id2 << ": 3s" << endl;

    signal(SIGALRM,alrm_handler);  //<<高?级?unix编?程?>>说?最?好?不?要?用?signal,?管?它?呢?,?这?个?简?单?,?用?sigacttion也?太?烦?了?吧?

    //set timer 0 5s
    struct itimerspec itmspec;
    struct timespec ts;
    
    //struct sigaction sa;
    //sigfillset(&sa.sa_mask);
    //sa.sa_flags = SA_SIGINFO;
    //sa.sa_sigaction = handler;
    itmspec.it_interval.tv_sec = 5;
    itmspec.it_interval.tv_nsec = 0;
    itmspec.it_value.tv_sec = 5;
    itmspec.it_value.tv_nsec = 0;


    time_t tm_show;
    time(&tm_show);


    timer_settime(tm_id, NULL,&itmspec,NULL);//第?二?个?参?数?为?,?则?与?setitimer相?似?,?第?四?个?参?数?返?回?旧?的?定?时?器?值?

    cout << "settime : " << (long)tm_show << "s " << endl;

    itmspec.it_interval.tv_sec = 3;
    itmspec.it_interval.tv_nsec = 0;
    itmspec.it_value.tv_sec = 3;
    itmspec.it_value.tv_nsec = 0;
    timer_settime(tm_id2, NULL,&itmspec,NULL);

    while(1);
    return 0;
}

makefile文件:

# # # # # # # # # # # # # # # # # # # # #
#  Makefile for pafone, general use
#                       2011.01.18
# # # # # # # # # # # # # # # # # # # # #

LIBS = -lrt
OBJS = main.o
TARGET = timer

#GCFLAGS :compile flags, GDFLAGS: link flags
GCFLAGS =
GDFLAGS =

GCC  = g++

all : $(OBJS)
    $(GCC) -o $(TARGET) $(OBJS) $(LIBS)
    @echo "compile success"

%.o : %.cpp
    $(GCC) $(GCFLAGS) -c $< -o $@

clean :
    rm -f $(TARGET) $(OBJS)

编译运行后的输出:

[root@pafone timer]# ./timer
timer_create return 0
tm_id0
timer_create return 0
tm_id1
set the timer 0: 5s
set timer 1: 3s
settime : 1295597124s
timer interrupt 14
settime : 1295597127s
timer interrupt 14
settime : 1295597129s
timer interrupt 14
settime : 1295597130s
timer interrupt 14
settime : 1295597133s

其中有一个是5s,另一个是3s的,但alrm_handler(int i)  函数传入来的i都是14,怎么区分是哪个定时器呢?    man 7 signal 发现里面的说明有说到handler的传入参数便是信号SIGALRM的#define值。

那么用sigacton可不可以区分是哪个定时器呢?还是一定要通过发送不同的信号来区分定时器

 

注:信号会中断一些阻塞调用及sleep()函数,例如将while(1)改为sleep()

itmspec.it_interval.tv_sec = 3;
itmspec.it_interval.tv_nsec = 0;
itmspec.it_value.tv_sec = 3;
itmspec.it_value.tv_nsec = 0;
timer_settime(tm_id2, NULL,&itmspec,NULL);

sleep(100);

输出是:

[root@pafone timer]# ./timer
timer_create return 0
tm_id0
timer_create return 0
tm_id1
set the timer 0: 5s
set timer 1: 3s
settime : 1295599530s
timer interrupt 14
settime : 1295599533s
[root@pafone timer]#

即它会在第一个定时信号后返回,也就是定时信号中断了sleep.

如用用sigaction, 其它一些系统调用可以设置SA_RESTART使调用继续,但对sleep不起作用。

你可能感兴趣的:(Linux)