在Linux下,我们可以使用POSIX提供的函数来创建定时器
int timer_create(clockid_t clockid, struct sigevent *sevp, timer_t *timerid);
clockid说明定时器是基于哪个时钟的,可以是下面的几个值:
CLOCK_REALTIME
CLOCK_MONOTONIC
CLOCK_PROCESS_CPUTIME_ID
CLOCK_THREAD_CPUTIME_ID
sevp设置了定时器到期的行为,通过sevp->sigev_notify进行设置:
SIGEV_SIGNAL:发送由evp->sigev_sino指定的信号到调用进程,evp->sigev_value的值将被作为siginfo_t结构体中si_value的值。
SIGEV_THREAD:以evp->sigev_notification_attributes为线程属性创建一个线程,在新建的线程内部以evp->sigev_value为参数调用evp->sigev_notification_function。
SIGEV_THREAD_ID:定时器到期时将向指定线程发送信号。下面是两个基于SIGEV_SIGNAL和SIGEV_THREAD的例子:
/*
* main.cpp
*
* Created on: 2014年11月9日
* Author: Richard
*/
#include <pthread.h>
#include <stdio.h>
#include <time.h>
#include <signal.h>
int Count = 0;
void signal_catcher(int signo)
{
Count++;
printf("Catch a signal %d\n", signo);
}
int main(int argc, char **argv) {
struct sigevent sig_event;
struct sigaction sig_action;
sigset_t sig_mask;
timer_t timer_id;
struct itimerspec timer_val;
//Set up a repeating timer using signal number SIGRTMIN,
//set to occur every 2 seconds.
sig_event.sigev_value.sival_int = 0;
sig_event.sigev_signo = SIGRTMIN;
sig_event.sigev_notify = SIGEV_SIGNAL;
//create timer
timer_create(CLOCK_REALTIME, &sig_event, &timer_id);
sigemptyset(&sig_mask);
sigaddset(&sig_mask, SIGRTMIN);
sig_action.sa_handler = signal_catcher;
sig_action.sa_mask = sig_mask;
sig_action.sa_flags = 0;
sigaction(SIGRTMIN, &sig_action, NULL);
timer_val.it_interval.tv_sec = 2;
timer_val.it_interval.tv_nsec = 0;
timer_val.it_value.tv_sec = 2;
timer_val.it_value.tv_nsec = 0;
timer_settime(timer_id, 0, &timer_val, NULL);
while(1)
{
if (Count >= 5) {
timer_settime(timer_id, 0, NULL, NULL);
break;
}
}
timer_delete(timer_id);
return 0;
}
/*
* main.cpp
*
* Created on: 2014年11月9日
* Author: Richard
*/
#include <pthread.h>
#include <stdio.h>
#include <time.h>
#include <signal.h>
int Count = 0;
void TimerThread(sigval_t sig)
{
int signo = sig.sival_int;
char *Content = (char *)sig.sival_ptr;
printf("signo: %d ,content: %s\n", signo, Content);
Count++;
}
int main(int argc, char **argv) {
struct sigevent sig_event;
timer_t timer_id;
struct itimerspec timer_val;
sig_event.sigev_notify = SIGEV_THREAD;
sig_event.sigev_value.sival_ptr=(void *)"Timer test";
sig_event.sigev_notify_function = TimerThread;
sig_event.sigev_notify_attributes = NULL;
//create timer
timer_create(CLOCK_REALTIME, &sig_event, &timer_id);
timer_val.it_interval.tv_sec = 2;
timer_val.it_interval.tv_nsec = 0;
timer_val.it_value.tv_sec = 2;
timer_val.it_value.tv_nsec = 0;
timer_settime(timer_id, 0, &timer_val, NULL);
while(1)
{
if (Count >= 5) {
timer_settime(timer_id, 0, NULL, NULL);
break;
}
}
timer_delete(timer_id);
return 0;
}
五次之后停止定时器,在返回前删除定时器。