POSIX定时器

在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_NONE:什么都不做,只提供通过timer_gettime和timer_getoverrun查询超时信息。

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;
}
五次之后停止定时器,在返回前删除定时器。

展开阅读全文

没有更多推荐了,返回首页