【Redis学习笔记】2018-06-04 timer

顺风车运营研发团队 周生政
定时器简介
POSIX的timer API 划分为下面的生命周期

  • timer_create() 系统调用创建一个timer并设置timer过期时调用的方法
  • timer_settime() 系统调用启动和停止一个timer
  • timer_delete() 删除一个timer

创建定时器

#define _POSIX_C_SOURCE 199309
#include <signal.h>
#include <time.h>
 
int timer_create(clockid_t clockid, struct sigevent *evp, timer_t *timerid);
 
                Returns 0 on success, or –1 on error

clockid可设置为:
CLOCK_REALTIME 可设置的系统实时时钟

CLOCK_MONOTONIC 不可设置的单调时钟

evp 当时间过期后程序怎么被通知

union sigval {
int sival_int; /* Integer value for accompanying data */
void *sival_ptr; /* Pointer value for accompanying data */
};
struct sigevent {
int sigev_notify; /* Notification method */
int sigev_signo; /* Timer expiration signal */
union sigval sigev_value; /* Value accompanying signal or  passed to thread function */
 
union {
pid_t _tid; /* ID of thread to be signaled /
struct {
void (*_function) (union sigval);
/* Thread notification function */
void *_attribute; /* Really 'pthread_attr_t *' */
} _sigev_thread;
} _sigev_un;
};

设置定时器

#define _POSIX_C_SOURCE 199309
#include <time.h>
int timer_settime(timer_t timerid, int flags, const struct itimerspec *value,
struct itimerspec *old_value);
 
Returns 0 on success, or –1 on error

参数 value设置定时器失效,old_value获取上一次时间,如果不关心可设置为null

struct itimerspec {
 
struct timespec it_interval; /* 周期性时间间隔 */
 
struct timespec it_value; /* 第一次失效时间 */
 
};
struct timespec {
 
time_t tv_sec; /* 秒 */
 
long tv_nsec; /* 纳秒 */
 
};

删除定时器

#define _POSIX_C_SOURCE 199309
 
#include <time.h>
 
int timer_delete(timer_t timerid);

例子

//signalDemo.cpp
//compile : gcc signalDemo.cpp -o testSignal -lrt
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
 
void testTimerSign();
void SignHandler(int iSignNo);
void printTime();
 
int main() {
    testTimerSign();
    while(true) {
        sleep(1);
    }
    return 0;
}
 
void SignHandler(int iSignNo){
    printTime();
    if(iSignNo == SIGUSR1){
        printf("Capture sign No.=SIGUSR1\n");
    }else{
        printf("Capture sign No.=%d\n",iSignNo);
    }
}
 
void testTimerSign(){
    struct sigevent evp; 
    struct itimerspec ts; 
    timer_t timer; 
    int ret; 
    evp.sigev_value.sival_ptr = &timer; 
    evp.sigev_notify = SIGEV_SIGNAL; 
    evp.sigev_signo = SIGUSR1; 
    signal(evp.sigev_signo, SignHandler);
    ret = timer_create(CLOCK_REALTIME, &evp, &timer); 
    if(ret) {
        perror("timer_create");
    }
    ts.it_interval.tv_sec = 1; // the spacing time 
    ts.it_interval.tv_nsec = 0; 
    ts.it_value.tv_sec = 2;  // the delay time start
    ts.it_value.tv_nsec = 0; 
    printTime();
    printf("start\n");
    ret = timer_settime(timer, 0, &ts, NULL); 
    if(ret) {
        perror("timer_settime");
    }
}
 
void printTime(){
    struct tm *cursystem;
    time_t tm_t;
    time(&tm_t);
    cursystem = localtime(&tm_t);
    char tszInfo[2048] ;
    sprintf(tszInfo, "%02d:%02d:%02d",
        cursystem->tm_hour, cursystem->tm_min,
        cursystem->tm_sec);
    printf("[%s]",tszInfo);
}

《【Redis学习笔记】2018-06-04 timer》

    原文作者:LNMPR源码研究
    原文地址: https://segmentfault.com/a/1190000015334649
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞