[Linux]Timer-定时器

一、timer_create() + timer_settime()定时器

精确到nsec级.

1.1 main.cpp

#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include<sys/time.h>

#define TIMER_SIVAL 9006

#define TIMER_START_TIME 3
#define TIMER_LOOP_TIME 1

struct timeval g_tv;
struct timezone g_tz;

void timer_thread(union sigval v)
{
    struct timeval tv;
    struct timezone tz;
    gettimeofday (&tv , &tz);
    printf("[sival:%d]sec:%ld,usec:%ld\n",v.sival_int,(tv.tv_sec - g_tv.tv_sec),(tv.tv_usec - g_tv.tv_usec));

}

int main()
{

    timer_t timerid;
    struct sigevent evp;
    memset(&evp, 0, sizeof(struct sigevent));       //清零初始化 

    evp.sigev_value.sival_int = TIMER_SIVAL;        //标识定时器的,回调函数可以获得 
    evp.sigev_notify = SIGEV_THREAD;                //线程通知的方式,派驻新线程 
    evp.sigev_notify_function = timer_thread;       //线程函数地址 

    if (timer_create(CLOCK_REALTIME, &evp, &timerid) == -1)
    {
        perror("fail to timer_create");
        exit(-1);
    }

    //第一次间隔it.it_value这么长,以后每次都是it.it_interval这么长,就是说it.it_value变0的时候会装载it.it_interval的值
    struct itimerspec it;
    it.it_interval.tv_sec = TIMER_LOOP_TIME; //回调函数执行频率为(tv_sec+tv_nsec)运行1次
    it.it_interval.tv_nsec = 0;
    it.it_value.tv_sec = TIMER_START_TIME;   //倒计时(tv_sec+tv_nsec)秒开始调用回调函数
    it.it_value.tv_nsec = 0;

    if (timer_settime(timerid, 0, &it, NULL) == -1)
    {
        perror("fail to timer_settime");
        exit(-1);
    }

    gettimeofday (&g_tv , &g_tz);

    //pause();
    while (1);

    return 0;
}

1.2 result

[sival:9006]sec:3,usec:93
[sival:9006]sec:4,usec:76
[sival:9006]sec:5,usec:78
[sival:9006]sec:6,usec:76
[sival:9006]sec:7,usec:79
[sival:9006]sec:8,usec:80
[sival:9006]sec:9,usec:74

二、信号量SIGALRM + alarm()定时器

精确到second级

2.1 main

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include<sys/time.h>

#define TIMER_START_TIME 3    
#define TIMER_LOOP_TIME 1     

struct timeval g_tv_before;
struct timeval g_tv_after;

void signal_handle(int sig)
{
    struct timeval tv;
    struct timezone tz;
    gettimeofday (&tv , &tz);
    printf("[sig:%d]sec:%ld,usec:%ld\n",sig,(tv.tv_sec - g_tv_before.tv_sec),(tv.tv_usec - g_tv_before.tv_usec));

    if(sig == SIGALRM){
       alarm(TIMER_LOOP_TIME);
    }

}

int main()
{

    signal(SIGALRM, signal_handle); //注册安装信号

    gettimeofday (&g_tv_before,NULL);

    alarm(TIMER_START_TIME);        //触发定时器 //精度能达到1秒,是无法低于1秒的精度

    gettimeofday (&g_tv_after,NULL);
    printf("[alarm cost]sec:%ld,usec:%ld\n",(g_tv_after.tv_sec - g_tv_before.tv_sec),(g_tv_after.tv_usec - g_tv_before.tv_usec));

    //pause();
    while (1);

    return 0;
}

2.2 result

[alarm cost]sec:0,usec:12
[sig:14]sec:3,usec:14
[sig:14]sec:4,usec:23
[sig:14]sec:5,usec:33
[sig:14]sec:6,usec:43
[sig:14]sec:7,usec:52

附:

Makefile

##dir
PWD_DIR=$(shell pwd)
OBJ_DIR=$(PWD_DIR)/obj
BIN_DIR=$(PWD_DIR)/bin

##compiler
CC=gcc

##target
TARGET=timer

##build
$(TARGET):main.o
        $(CC) main.o -o $@ -lrt
main.o:main.cpp
        $(CC) -c $^ 
clean:
        rm -rf *.o timer
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值