timer_create定时器

8 篇文章 0 订阅
8 篇文章 1 订阅

主要内容参考了文章https://blog.csdn.net/sinat_36184075/article/details/80489402

头文件:
#include <time.h>

函数声明:
int timer_settime(timer_t timerid, int flags, const struct itimerspec * new_value, struct itimerspec * old_value);
int timer_gettime(timer_t timerid, struct itimerspec * curr_value);

功能:设置或者获得定时器时间值
参数:
     @timerid 定时器标识
     @flags 0标识相对时间,1标识绝对时间
     @new_value 定时器的新初始值和间隔
     @old_value 取值通常为0或NULL,若不为NULL,则返回定时器前一个值
编译:
     编译时增加选项 -lrt.

union sigval
{
    int sival_int; //integer value
    void *sival_ptr; //pointer value
}

struct sigevent
{
    int sigev_notify;                 //notification type
    int sigev_signo;                 //notification signal number
    union sigval   sigev_value;     //Data passed with notification
    void (*sigev_notify_function)(union sigval);    /* Function used for thread notification (SIGEV_THREAD) */
    pthread_attr_t *sigev_notify_attributes;        /* Attributes for notification thread (SIGEV_THREAD) */
}

通过将 sigevent中的sigev_notify设定为如下值来定制定时器到期后的行为:
SIGEV_NONE:什么都不做,只提供通过timer_gettime和timer_getoverrun查询超时信息。
SIGEV_SIGNAL: 当定时器到时,内核会将sigev_signo所指定的信号传送给进程。在信号处理程序中,si_value会被设定会sigev_value。
SIGEV_THREAD: 当定时器到时,内核会(在此进程内)以sigev_notification_attributes为线程属性创建一个线程,并且让它执行sigev_notify_function,传入sigev_value作为为一个参数。

struct timespec {
               time_t tv_sec;                /* Seconds */
               long   tv_nsec;               /* Nanoseconds */
};

struct itimerspec {
               struct timespec it_interval;  /* Timer interval */
               struct timespec it_value;     /* Initial expiration */
};
 
函数声明:
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
参数:
    signum--指定的信号,这里使用SIGUSR1
    act结构体--设置信号编号为signum的处理方式
    oldact结构体--保存上次的处理方式
结构体:
    struct sigaction   
    {
        void (*sa_handler)(int);                             //信号响应函数地址
        void (*sa_sigaction)(int, siginfo_t *, void *);       //当sa_flags为SA——SIGINFO时才使用
        sigset_t sa_mask;                                     //说明一个信号集在调用捕捉函数之前,会加入进程的屏蔽中,当捕捉函数返回时,还原
        int sa_flags;                                         //设置成0时,sa_handler指向一个参数的函数
        void (*sa_restorer)(void);   //未用
    };

举例1:采用新线程派驻的通知方式

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

static int count = 10;	//执行10次后结束
void timer_thread(union sigval v) 
{ 
	count--;
    printf("%s param: %d, count: %d\n", __FUNCTION__, v.sival_int, count); 
} 

int main() 
{ 
    timer_t timerid; 
    struct sigevent evp; 
    memset(&evp, 0, sizeof(struct sigevent));       //清零 

    evp.sigev_value.sival_int = 12;                 //标识定时器,回调函数可以获得 
    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时调用 
    struct itimerspec it; 
    it.it_interval.tv_sec = 2;  // timer函数执行频率为2s运行1次
    it.it_interval.tv_nsec = 0; 
    it.it_value.tv_sec = 4;     // 倒计时4秒开始调用timer函数
    it.it_value.tv_nsec = 0; 

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

    while (count);	

    return 0; 
} 

举例2:通知方式为信号的处理方式

#include <stdio.h> 
#include <time.h> 
#include <stdlib.h> 
#include <signal.h> 
#include <string.h> 
#include <unistd.h> 
 
#define CLOCKID CLOCK_REALTIME 

void sig_handler(int signo) 
{ 
    printf("timer_signal function! %d\n", signo); 
} 

int main() 
{ 
    timer_t timerid; 
    struct sigevent evp; 

    struct sigaction act; 
    memset(&act, 0, sizeof(act)); 
    act.sa_handler = sig_handler; 
    act.sa_flags = 0; 

    // XXX int sigaddset(sigset_t *set, int signum);  //将signum指定的信号加入set信号集
    // XXX int sigemptyset(sigset_t *set);          //初始化信号集 
	
    sigemptyset(&act.sa_mask); 
	//SIGUSR1 用户自定义信号 默认处理:进程终止
	//SIGUSR2 用户自定义信号 默认处理:进程终止
    if (sigaction(SIGUSR1, &act, NULL) == -1) 
    { 
        perror("fail to sigaction"); 
        exit(-1); 
    } 

    memset(&evp, 0, sizeof(struct sigevent));
    evp.sigev_signo = SIGUSR1; 
    evp.sigev_notify = SIGEV_SIGNAL; 
    if (timer_create(CLOCK_REALTIME, &evp, &timerid) == -1) 
    { 
        perror("fail to timer_create"); 
        exit(-1); 
    } 

    struct itimerspec it; 
    it.it_interval.tv_sec = 2; 
    it.it_interval.tv_nsec = 0; 
    it.it_value.tv_sec = 1; 
    it.it_value.tv_nsec = 0; 
    if (timer_settime(timerid, 0, &it, 0) == -1) 
    { 
        perror("fail to timer_settime"); 
        exit(-1); 
    } 
	
	struct itimerspec newit;
	if (timer_gettime(timerid, &newit) == 0)
	{
		printf("interval.tv_sec: %ld \n interval.tv_nsec: %ld \n value.tv_sec: %ld \n value.tv_nsec: %ld \n",
			newit.it_interval.tv_sec, newit.it_interval.tv_nsec, newit.it_value.tv_sec, newit.it_value.tv_nsec);
	}
 
    while(1); 

    return 0; 

} 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值