Linux 定时器的使用
来源:互联网 发布:斗地主残局软件 编辑:程序博客网 时间:2024/05/19 03:29
Linux 定时器的使用有很多方法,常用的两种方式:
1.alarm
2.setitimer
一、alarm
1.函数介绍
signal()
函数原型 :
void (*signal(int signum,void(* handler)(int)))(int);
或者:typedef void(*sig_t) ( int ); sig_t signal(int signum,sig_t handler);
参数说明:
第一个参数signum指明了所要处理的信号类型,它可以取除了SIGKILL和SIGSTOP外的任何一种信号。
第二个参数handler描述了与信号关联的动作,它可以取以下三种值:
(1)一个返回值为正数的函数地址 此函数必须在signal()被调用前申明,handler中为这个函数的名字。当接收到一个类型为sig的信号时,就执行handler 所指定的函数。这个函数应有如下形式的定义: intfunc(int sig); sig是传递给它的唯一参数。执行了signal()调用后,进程只要接收到类型为sig的信号,不管其正在执行程序的哪一部分,就立即执行func()函数。当func()函数执行结束后,控制权返回进程被中断的那一点继续执行。
(2)SIGIGN 这个符号表示忽略该信号,执行了相应的signal()调用后,进程会忽略类型为sig的信号。
(3)SIGDFL 这个符号表示恢复系统对信号的默认处理。
函数说明 : signal()会依参数signum 指定的信号编号来设置该信号的处理函数。当指定的信号到达时就会跳转到参数handler指定的函数执行。当一个信号的信号处理函数执行时, 如果进程又接收到了该信号,该信号会自动被储存而不会中断信号处理函数的执行,直到信号处理函数执行完毕再重新调用相应的处理函数。但是如果在信号处理函数执行时进程收到了其它类型的信号,该函数的执行就会被中断。
返回值: 返回先前的信号处理函数指针,如果有错误则返回SIG_ERR(-1)。
附加说明 :在信号发生跳转到自定的handler处理函数执行后,系统会自动将此处理函数换回原来系统预设的处理方式,如果要改变此操作请改用sigaction()。
下面的情况可以产生Signal:
1. 按下CTRL+C产生SIGINT
2. 硬件中断,如除0,非法内存访问(SIGSEV)等等
3. Kill函数可以对进程发送Signal
4. Kill命令。实际上是对Kill函数的一个包装
5. 软件中断。如当Alarm Clock超时(SIGURG),当Reader中止之后又向管道写数据(SIGPIPE),等等
2 Signals:
alarm()
所需头文件
#include<unistd.h>
函数原型
unsigned int alarm(unsigned int seconds)
函数参数
seconds:指定秒数
函数返回值
成功:如果调用此alarm()前,进程已经设置了闹钟时间,则返回上一个闹钟时间的剩余时间,否则返回0。
出错:-1
- #include <stdio.h>
- #include <unistd.h>
- #include <signal.h>
- void sigalrm_fn(int sig)
- {
- printf("alarm!\n");
- alarm(2);
- return;
- }
- int main(void)
- {
- signal(SIGALRM, sigalrm_fn);
- alarm(2);
-
- while(1) pause();
- }
函数说明:
int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue));
which为定时器类型,setitimer支持3种类型的定时器:
ITIMER_REAL : 以系统真实的时间来计算,它送出SIGALRM信号。
ITIMER_VIRTUAL : -以该进程在用户态下花费的时间来计算,它送出SIGVTALRM信号。
ITIMER_PROF : 以该进程在用户态下和内核态下所费的时间来计算,它送出SIGPROF信号。
setitimer()第一个参数which指定定时器类型(上面三种之一);第二个参数是结构itimerval的一个实例;第三个参数可不做处理。
setitimer()调用成功返回0,否则返回-1。
struct itimerval {
struct timeval it_interval;
struct timeval it_value;
};
struct timeval {
long tv_sec;
long tv_usec;
};
it_interval指定间隔时间,it_value指定初始定时时间。如果只指定it_value,就是实现一次定时;如果同时指定 it_interval,则超时后,系统会重新初始化it_value为it_interval,实现重复定时;两者都清零,则会清除定时器。
tv_sec提供秒级精度,tv_usec提供微秒级精度,以值大的为先,注意1s = 1000000us。
ovalue用来保存先前的值,常设为NULL。
如果是以setitimer提供的定时器来休眠,只需阻塞等待定时器信号就可以了。
demo:- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <signal.h>
- #include <time.h>
- #include <sys/time.h>
- int sec;
- void sigroutine(int signo){
- switch (signo){
- case SIGALRM:
- printf("Catch a signal -- SIGALRM \n");
- signal(SIGALRM, sigroutine);
- break;
- case SIGVTALRM:
- printf("Catch a signal -- SIGVTALRM \n");
- signal(SIGVTALRM, sigroutine);
- break;
- }
- return;
- }
- int main()
- {
- struct itimerval value, ovalue, value2;
- sec = 5;
- printf("process id is %d ", getpid());
- signal(SIGALRM, sigroutine);
- signal(SIGVTALRM, sigroutine);
- value.it_value.tv_sec = 1;
- value.it_value.tv_usec = 0;
- value.it_interval.tv_sec = 1;
- value.it_interval.tv_usec = 0;
- setitimer(ITIMER_REAL, &value, &ovalue);
- value2.it_value.tv_sec = 0;
- value2.it_value.tv_usec = 500000;
- value2.it_interval.tv_sec = 0;
- value2.it_interval.tv_usec = 500000;
- setitimer(ITIMER_VIRTUAL, &value2, &ovalue);
- for(;;);
- }
- linux定时器的使用
- linux定时器的使用
- linux定时器的使用
- linux定时器的使用
- Linux定时器的使用
- linux定时器的使用
- linux定时器的使用
- linux定时器的使用
- linux定时器的使用
- Linux定时器的使用
- Linux定时器的使用
- linux定时器的使用
- linux定时器的使用
- Linux定时器的使用
- linux定时器的使用
- Linux定时器的使用
- Linux定时器的使用
- linux定时器的使用
- 使用Android Studio生成javadoc
- This version of android studio is incompatible with the gradle version used.
- android Error:Error: Expected resource of type string [ResourceType]
- js怎么获取元素的宽高
- Flink流计算与时序数据库Influxdb+grafana
- Linux 定时器的使用
- 基本操作命令(From菜鸟教程)
- 容器
- 文件为图片的格式验证
- android开发之在不加载图片的前提下获得图片的宽高
- reference to 'Size' is ambiguous, candidate found by name lookup is 'Size', 'cv::Size'
- 八皇后问题
- leetcode 412 Fizz Buzz C++
- SQL 笔记