前言
如果,想要深入的学习Linux系统调用中的alarm、setitimer函数,还是需要去自己阅读Linux系统中的帮助文档。
具体输入命令:
man 2 alarm/setitimer
即可查阅到完整的资料信息。
alarm 函数
alarm() 是一个 Linux 系统调用,用于设置一个实时闹钟,
当指定的时间(以秒为单位)到达时,系统会发送一个 SIGALRM 信号给进程
。
- 这个信号通常用于限制某个程序或者操作的执行时间。当闹钟时间到达时,若没有设置信号处理程序,进程将被终止。
- 如果设置了信号处理程序,那么在信号处理程序执行完毕后,进程会继续执行。
alarm() 系统调用的原型如下:
#include <unistd.h> //使用此函数,需导入此头文件unsigned int alarm(unsigned int seconds);
参数:
- seconds:闹钟的延迟时间,以秒为单位。如果传入 0,则取消之前设置的闹钟。
返回值:
- 如果之前没有设置闹钟,返回 0;
- 如果之前设置了闹钟,返回距离上一个闹钟剩余的秒数。
示例:
- 下面的示例程序设置一个 5 秒的闹钟,当闹钟时间到达时,会收到 SIGALRM 信号,并执行 sig_handler 函数,打印一条消息。
#include <stdio.h>
#include <unistd.h>
#include <signal.h>void sig_handler(int signum) {printf("Received SIGALRM, timer expired!\n");
}int main() {signal(SIGALRM, sig_handler);alarm(5);printf("Waiting for alarm...\n");pause(); // Suspend the process until a signal is receivedprintf("Exiting...\n");return 0;
}
请注意,alarm() 函数只能设置一个闹钟。如果在一个闹钟到期之前再次调用 alarm(),则之前的闹钟将被新的闹钟替代
。
setitimer 函数
setitimer() 是一个 Linux 系统调用,用于设置一个间隔性定时器。与 alarm() 函数相比,setitimer() 提供了更高级的功能,支持设置多个定时器以及定时器的更精确控制。当定时器到期时,系统会发送一个信号给进程,通常用于限制程序或操作的执行时间、定期执行任务等。
setitimer() 系统调用的原型如下:
#include <sys/time.h> // 使用此函数需导入此头文件int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);
参数:
-
which:指定设置哪种类型的定时器。有以下三种类型:
-
ITIMER_REAL:以实时时间递减,到期后发送 SIGALRM 信号。
-
ITIMER_VIRTUAL:只有在进程执行时才递减,到期后发送 SIGVTALRM 信号。
-
ITIMER_PROF:在进程执行和系统执行内核代码时递减,到期后发送 SIGPROF 信号。
-
new_value:指向一个 itimerval 结构体,用于设置定时器的初始值和间隔。
-
old_value:指向一个 itimerval 结构体,如果不为 NULL,用于保存先前设置的定时器值。
- itimerval 结构体定义如下:
struct itimerval {struct timeval it_interval; // 间隔时间struct timeval it_value; // 初始时间 };
- timeval 结构体定义如下:
struct timeval {long tv_sec; // 秒数 long tv_usec; // 微秒数 };
返回值:
- 成功时返回 0;
- 出错时返回 -1,并设置相应的 errno。
与 alarm() 的区别:
- setitimer() 支持多个定时器(ITIMER_REAL、ITIMER_VIRTUAL 和 ITIMER_PROF),而 alarm() 只支持一个定时器。
- setitimer() 可以设置定时器的间隔时间,使定时器在到期后自动重置,而 alarm() 只能在指定的时间后触发一次。
- setitimer() 支持微秒级的时间精度,而 alarm() 只支持秒级的精度。
示例:
- 下面的示例程序设置一个实时定时器,初始值为 3 秒,之后每隔 2 秒触发一次。
- 当定时器到期时,会收到 SIGALRM 信号,并执行 sig_handler 函数,打印一条消息。
- 在未收到信号之前,while循环会每隔1秒打印一条信息。
- 我们可以使用ctrl + C 键来结束进程。
#include <sys/time.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void sighandler_t(int signal){static int i = 0;++i;printf("第%d次收到信号\n",i);
}int main(){signal(SIGALRM,sighandler_t);struct itimerval timer;timer.it_interval.tv_sec = 2;timer.it_interval.tv_usec = 0;timer.it_value.tv_sec = 3;timer.it_value.tv_usec = 0;if(setitimer(ITIMER_REAL,&timer,NULL) == -1){perror("setitimer");exit(0);}while(1){printf("等待信号…\n");sleep(1);}return 0;
}
总结
- setitimer() 支持多个定时器(ITIMER_REAL、ITIMER_VIRTUAL 和 ITIMER_PROF),而 alarm() 只支持一个定时器。
- setitimer() 可以设置定时器的间隔时间,使定时器在到期后自动重置,而 alarm() 只能在指定的时间后触发一次。
- setitimer() 支持微秒级的时间精度,而 alarm() 只支持秒级的精度。
最后的最后,如果你觉得我的这篇文章写的不错的话,请给我一个赞与收藏,关注我,我会继续给大家带来更多更优质的干货内容。