博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux下的定时器以及POSIX定时器:timer_settime()
阅读量:4050 次
发布时间:2019-05-25

本文共 4328 字,大约阅读时间需要 14 分钟。


Linux下的定时器有两种:

1、alarm

  如果不要求很精确的话,用alarm()和signal()就够了。

  unsigned int alarm(unsigned int seconds)

  函数说明: alarm()用来设置信号SIGALRM在经过参数seconds指定的秒数后传送给目前的进程。如果参数seconds为0,则之前设置的闹钟会被取消,并将剩下的时间返回。

  返回值: 返回之前闹钟的剩余秒数,如果之前未设闹钟则返回0.

  alarm()执行后,进程将继续执行,在后期(alarm以后)的执行过程中将会在seconds秒后收到信号SIGALRM并执行其处理函数。

举例:

(1)

#include 
#include
#include
#include
#include
int count;void sigalrm_func(int sig){ count++; printf("alarm![%d]\n",count); alarm(2); printf("over\n"); return; }int main(void){ signal(SIGALRM, sigalrm_func); alarm(3); printf("see\n"); while(1); }

(2)

#include 
#include
#include
#include
//alarm()所在库 int main(int argc, char *argv[]) { sigset_t block; sigemptyset(&block); sigaddset(&block, SIGALRM); sigprocmask(SIG_BLOCK, &block, NULL); while (1) { printf("%ld\n", time(NULL)); alarm(3); printf("see\n"); sigwaitinfo(&block, NULL); } return 0; }

2、函数alarm设置的定时器只能精确到秒,而以下函数理论上可以精确到微妙:

#include 
int getitimer(int which, struct itimerval *value);int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);

setitimer()比alarm功能强大,支持3种类型的定时器(参数which):

第一个参数which指定定时器类型;

第二个参数是结构itimerval的一个实例;

第三个参数可不做处理。

setitimer()调用成功返回0,否则返回-1.

参数which确定了定时器的类型,如表1所示:

表1 参数which与定时器类型

这里写图片描述

结构itimerval描述了定时器的组成:

struct itimerval {    struct tim it_interval;     /* 下次定时取值 */    struct tim it_value;    /* 本次定时设置值 */}

结构tim描述了一个精确到微妙的时间:

struct tim{    longtv_sec;                 /* 秒(1000000微秒) */    longtv_usec;                /* 微妙 */}

函数setitimer设置一个定时器,参数value指向一个itimerval结构,该结构决定了设置的定时器信息,结构成员it_value指定首次定时的时间,结构成员it_interval指定下次定时的时间。

定时器工作时,先将it_value的时间值减到0,发送一个信号,再将it_value赋值为it_interval的值,重新开始定时,如此反复。如果it_value值被设置为0,则定时器停止定时;如果it_value值不为0但it_interval值为0,则定时器在一次定时后终止。

函数setitimer调用成功时返回0,否则返回-1,参数ovalue如果不为空,返回上次的定时器状态。

函数getitimer获取当前的定时器状态,整型参数which指定了读取的定时器类型,参数value返回定时器状态。函数调用成功返回0,否则返回-1。

举例(1)

#include 
#include
#include
#include
int count = 0; void set_timer() { struct itimerval itv; itv.it_interval.tv_sec = 1;//每隔1秒 itv.it_interval.tv_usec = 0; itv.it_value.tv_sec = 3;//第一次3秒 itv.it_value.tv_usec = 0; setitimer(ITIMER_REAL, &itv, NULL); } void sigalrm_handler(int sig) { count++; printf("timer signal.. %d\n", count); } int main() { signal(SIGALRM, sigalrm_handler); set_timer(); while (count < 100) {} exit(0); }

(2)

#include 
#include
#include
#include
int main(int argc, char *argv[]) { sigset_t block; struct itimerval itv; sigemptyset(&block); sigaddset(&block, SIGALRM); sigprocmask(SIG_BLOCK, &block, NULL); itv.it_interval.tv_sec = 5; itv.it_interval.tv_usec = 0; itv.it_value = itv.it_interval; setitimer(ITIMER_REAL, &itv, NULL); while (1) { printf("%ld\n", time(NULL)); printf("see\n"); sigwaitinfo(&block, NULL); } return 0; }

3、信号相关

#include 
int sigwaitinfo(sigset_t *set, siginfo_t *info)

sigwaitinfo()函数:阻塞一个进程直到特定信号发生,但信号到来时不执行信号处理函数,而是返回信号值。 调用该函数的典型代码为:

sigwaitinfo()sigset_t newmask;int rcvd_sig;siginfo_t info;sigemptyset(&newmask);sigaddset(&newmask, SIGRTMIN);sigprocmask(SIG_BLOCK, &newmask, NULL);rcvd_sig = sigwaitinfo(&newmask, &info);if(rcvd_sig == -1){…...}

1.信号集定义为一种数据类型,用来描述信号的集合:

typedef struct{    unsigned long sig[_NSIG_WORDS];     }sigset_t

2.int sigemptyset(sigset_t* set)

函数说明:用来将参数set信号集初始化并清空。

返回值:成功返回0,错误返回-1。

3.int sigaddset(sigset_t* set, int signum)

函数说明:用来将signum代表的信号加入至参数set信号集里。

返回值:成功返回0,错误返回-1。

4.int sigpromask(int how, const sigset_t* set, sigset_t* oldset)

函数说明:用来改变目前的信号遮罩,其操作依参数how来决定。

返回值:成功返回0,错误返回-1。

5.void (signal(int signum, void( handler)(int)))(int);

函数说明: signal()会依据参数signum指定的信号编号来设置该信号的处理函数,当指定的信号到达时就会跳转参数handler指定的函数执行。

返回值:返回先前的信号处理函数指针,如果有错误返回SIG_ERR(-1)

参考文章:

1.Linux下的定时器:
2.linux的定时器(timer_create,timer_gettime,timer_delete,SIGEV_SIGNAL):

POSIX定时器:timer_settime()以及POSIX 线程见下一篇。

你可能感兴趣的文章
Node.js中的事件驱动编程详解
查看>>
mongodb 命令
查看>>
MongoDB基本使用
查看>>
mongodb管理与安全认证
查看>>
nodejs内存控制
查看>>
nodejs Stream使用中的陷阱
查看>>
MongoDB 数据文件备份与恢复
查看>>
数据库索引介绍及使用
查看>>
MongoDB数据库插入、更新和删除操作详解
查看>>
MongoDB文档(Document)全局唯一ID的设计思路
查看>>
mongoDB简介
查看>>
Redis持久化存储(AOF与RDB两种模式)
查看>>
memcached工作原理与优化建议
查看>>
Redis与Memcached的区别
查看>>
redis sharding方案
查看>>
程序员最核心的竞争力是什么?
查看>>
Node.js机制及原理理解初步
查看>>
linux CPU个数查看
查看>>
分布式应用开发相关的面试题收集
查看>>
简单理解Socket及TCP/IP、Http、Socket的区别
查看>>