Linux中alarm/setitimer函数(信号函数)

alarm函数

函数原型: unsigned int alarm(unsigned int seconds);

函数描述:设置定时器(闹钟)。在指定seconds后,内核会给当前进程发送 14)SIGALRM信号。进程收到该信号,默认动作终止。每个进程都有且唯一的一个定时器。

函数返回值:返回0或者剩余的秒数,无失败。

alarm() returns the number of seconds remaining  until  any  previously
       scheduled alarm was due to be delivered, or zero if there was no previ‐
       ously scheduled alarm.

alarm(5)-----------sleep(2)---------->alarm(5)->接下来还是5秒后产生SIGALRM信号

return 0; return 3(之前的定时器还差3second结束);

取消定时器:alarm(0),返回旧闹钟剩余的秒数

测试:

cpp 复制代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
#include <signal.h>
void handler(int signo)
{
	printf("signo==[%d]\n",signo);
}
int main()
{
//给内核注册信号捕捉函数,看看是不是发送SIFGALRM信号
	signal(SIGALRM,handler);

	int n=alarm(10);
	printf("n==[%d]\n",n);
	sleep(2);

	n=alarm(2);//2秒后发送信号
	printf("n==[%d]\n",n);

	sleep(5);//让进程休息5秒,不然进程结束,也收不到信号了
}

运行结果我们也可以发现给进程发出SIGALRM信号时,该进程 直接终止**,并没有sleep(5)那么久才结束 (** 由于 alarm() 函数被 sleep() 函数替代,可能会对定时器造成影响。如果你希望在接收到 SIGALRM 信号后再等待 10 秒钟,可以将 sleep(10) 移到信号处理函数中,并在接收到信号后调用 sleep() 函数。

闹钟实际执行时间=系统时间+用户时间+损耗时间

我们通过测试电脑一秒中能打印多少的数字(printf("[%d]\n",i++);)可知:

调用printf函数打印数字遇到\n才会打印,打印过程涉及到从用户区到内核区的切换(打印一次切换一次),切换次数越多消耗的时间越长,效率越低,损耗的时间越多。

而我们使用文件重定向操作时(./ arlarm > test.log->写到test.log),由于文件操作带缓冲,所以涉及到用户区到内核区的切换次数大大减少(缓冲区满了才从用户区切换到内核区),从而使损耗大大降低

setitimer函数:

函数原型: int setitimer(int which, const struct itimerval *new_value,

struct itimerval *old_value);

函数作用:设置定时器,可代替alarm函数,精度微秒us,可以实现周期定时。

函数参数:

which:指定定时方式

自然定时:ITIMER_REAL(计算自然时间) This  timer counts down in real (i.e., wall clock) time.
                      At each expiration, a SIGALRM(14) signal is generated.

虚拟空间计时(用户空间):ITIMER_VIRTUAL(只计算进程占用cpu的时间) This timer counts down against the  user-mode  CPU  time
                      consumed  by the process.  (The measurement includes CPU
                      time consumed by all threads in the process.)   At  each
                      expiration, a SIGVTALRM signal is generated.

运行时计时(用户+内核)ITIMER_PROF(计算占用cpu及执行系统调用的时间)    This  timer  counts  down  against the total (i.e., both
                      user and system) CPU time consumed by the process.  (The
                      measurement includes CPU time consumed by all threads in
                      the process.)  At each expiration, a SIGPROF  signal  is
                      generated.

                      In  conjunction  with  ITIMER_VIRTUAL, this timer can be
                      used to profile user and system CPU time consumed by the
                      process.

new value:负责设定timeout时间

old_value:存放旧的timeout值,一般设为NULL

 struct itimerval {
           struct timeval it_interval;设定以后每几秒执行function(周期)
               struct timeval it_value;设定什么时候执行第一次function
           };

           struct timeval {
               time_t      tv_sec;         秒
               suseconds_t tv_usec;       微秒
           };

测试;

cpp 复制代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
#include <signal.h>
#include <sys/time.h>
void handler(int signo)
{
	printf("signo=[%d]\n",signo);
//alarm(0);可以取消计时器
}
int main()
{
//	signal(SIGALRM,handler);
	//int setitimer(int which, const struct itimerval *new_value,
	//   struct itimerval *old_value);
	struct itimerval value;
//设置间隔
	value.it_interval.tv_sec=1;
	value.it_interval.tv_usec=0;//因为在栈上,不初始化会随机值
//设置第一次发信号的时间
	value.it_value.tv_sec=2;
	value.it_value.tv_usec=0;

	setitimer(ITIMER_REAL,&value,NULL);
//一直执行进程
	while(1)
	{
		sleep(1);
	}

}

结果:2秒之后每隔1秒打印编号:

如果我们不写SIGALRM的信号处理函数,接收到SIGALRM后会直接终止进程(默认行为)。

相关推荐
Komorebi.py17 分钟前
【Linux】-学习笔记05
linux·笔记·学习
Mr_Xuhhh23 分钟前
重生之我在学环境变量
linux·运维·服务器·前端·chrome·算法
中云DDoS CC防护蔡蔡1 小时前
微信小程序被攻击怎么选择高防产品
服务器·网络安全·微信小程序·小程序·ddos
HPC_fac130520678162 小时前
以科学计算为切入点:剖析英伟达服务器过热难题
服务器·人工智能·深度学习·机器学习·计算机视觉·数据挖掘·gpu算力
yaoxin5211233 小时前
第二十七章 TCP 客户端 服务器通信 - 连接管理
服务器·网络·tcp/ip
内核程序员kevin3 小时前
TCP Listen 队列详解与优化指南
linux·网络·tcp/ip
sinat_384241098 小时前
使用 npm 安装 Electron 作为开发依赖
服务器
朝九晚五ฺ8 小时前
【Linux探索学习】第十四弹——进程优先级:深入理解操作系统中的进程优先级
linux·运维·学习
自由的dream8 小时前
Linux的桌面
linux
xiaozhiwise8 小时前
Makefile 之 自动化变量
linux