本来想写下自己的东西,但看到有一篇文章写得很好,于是就不自己写了。

出处:https://typecodes.com/linux/linuxalarmknockfunc.html

1. alarm函数

[1] 引用头文件:#include <unistd.h>;[2] 函数标准式:unsigned int alarm(unsigned int seconds);[3] 功能与作用:alarm()函数的主要功能是设置信号传送闹钟,即用来设置信号SIGALRM在经过参数seconds秒数后发送给目前的进程。如果未设置信号SIGALARM的处理函数,那么alarm()默认处理终止进程。[4] 函数返回值:如果在seconds秒内再次调用了alarm函数设置了新的闹钟,则后面定时器的设置将覆盖前面的设置,即之前设置的秒数被新的闹钟时间取代;当参数seconds为0时,之前设置的定时器闹钟将被取消,并将剩下的时间返回。


2. 测试

原文的测试环境是RedHat Linux5.3,本人在Ubuntu 14.04中再次进行了测试。测试结果与原作者一致。

了解了alarm()函数的功能特性和返回值的特性后,我们就可以对其测试。测试方向有两个:其一,测试常规只单独存在一个闹钟函数alarm()的程序;其二,测试程序中包含多个alarm()闹钟函数。因此整理了下面几个程序,通过比较学习更有助于理解。测试环境是RedHat Linux5.3,GCC编译调试。

2.1 alarm()测试1.1
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>void sig_alarm()
{ exit(0);
}
int main(int argc, char *argv[])
{ signal(SIGALRM, sig_alarm); alarm(10); sleep(15); printf("Hello World!\n"); return 0;
}

程序分析:在文件test1.c中,定义了一个时钟alarm(10),它的作用是让信号SIGALRM在经过10秒后传送给目前main()所在进程;接着又定义了sleep(15),它的作用是让执行挂起15秒的时间。所以当main()程序挂起10秒钟时,signal函数调用SIGALRM信号的处理函数sig_alarm,并且sig_alarm执行exit(0)使得程序直接退出。因此,printf("Hello World!\n")语句是没有被执行的。

2.2 alarm()测试1.2
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>void sig_alarm()
{ exit(0);
}
int main(int argc, char *argv[])
{ signal(SIGALRM, sig_alarm); alarm(10); sleep(5); printf("Hello World!\n"); return 0;
}

程序分析:与test1.c文件不同的是,在文件test2.c中延时函数为sleep(5),即执行挂起5秒的时间。所以当main()程序挂起5秒钟时,由于还没到达设置的闹钟10秒,那么main就执行下面的printf("Hello World!\n")语句;紧接着又执行下面的return 0语句,从而直接退出程序。因此,整个test2.c文件输出的内容为:Hello World!。

2.3 alarm()测试2
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>void handler()
{printf("hello\n");
}void main()
{int i;signal(SIGALRM, handler);alarm(5);for(i = 1; i < 7; i++){printf("sleep %d ...\n", i);sleep(1);}
}

程序分析:在文件test3.c中,定义时钟alarm(5),而main()函数中主要是一个for循环输出语句。当main函数执行到i=5时,for循环先执行printf("sleep %d ...\n", 5)语句输出"sleep 5 ...",然后执行sleep(1)语句。此时已经到达闹钟时间5秒,因此会把信号SIGALRM传送给当前main()函数进程;接着调用SIGALRM信号的处理函数handler,从而输出"hello",然后又返回到sleep(1)这个点;最后for循环执行i=6,输出"sleep 6",最终延时1秒后结束整个程序。

以上三个程序都只包含一个alarm()闹钟函数,下面两个程序包含两个alarm()。并且为了更为真切的观察包含alarm()闹钟函数的程序的执行过程,程序通过调用系统打印输出当前时间,通过时间差来进一步理解。

2.4 alarm()测试3.1
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>static void sig_alrm(int signo);
int main(void)
{signal(SIGALRM,sig_alrm);system("date");alarm(20);sleep(5);printf("%d\n",alarm(15));pause();
}static void sig_alrm(int signo){system("date");return;
}

程序分析:在test4.c的main()函数中,先设置了一个闹钟函数alarm(20),即在20秒时将SIGALRM信号传送送给当前进程;然后又定义了一个延时函数sleep(5),接着又定义了一个闹钟函数alarm(15),它的作用是清除前面设置的闹钟alarm(20)并返回剩余的时间20-5=15秒。所以,程序先执行system("date")语句输出当前时间;然后进程休眠5秒后,程序执行输出语句printf("%d\n",alarm(15)),由于alarm(15)先返回15秒,即打印输出15;接着程序执行pause()函数,使当前进程处于挂起状态,直到捕捉到一个信号;当再过15秒后,SIGALARM信号的处理函数sig_alrm执行system("date")语句输出当前时间;最后pause终止进程。因此,整个程序执行的时间为5+15=20秒。

2.5 alarm()测试3.2
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>static void sig_alrm(int signo);
int main(void)
{signal(SIGALRM,sig_alrm);system("date");alarm(20);sleep(5);printf("%d\n",alarm(5));pause();
}static void sig_alrm(int signo){system("date");return;
}

程序分析:与test4.c文件不同的是,在文件test5.c中闹钟函数为alarm(5)。因此,整个程序执行的时间为5+5=10秒。值得注意的是,alarm(0)表示清除之前设置的闹钟信号,并返回0。因为,如果这里把alarm(5)改成alarm(0),那么整个程序执行的时间为5+0=5秒。


最后:需要注意的是,原作者在文章中进行了精确的时间计算,而程序运行的结果也与作者的计算一致,但即使如此,精确的结果也是不可信的和计算精确的结果也是不可行的。在某些条件下,我们实际花费和等待的时间很有可能比程序设定的时间要长,而且1秒对于现代的操作系统来说,实在是太长了。

小记——linux定时器之alarm相关推荐

  1. linux定时器之alarm

    出处:http://blog.csdn.net/u010155023/article/details/51984602 1. alarm函数 [cpp] view plaincopy [1] 引用头文 ...

  2. linux alarm 多个,linux中的alarm和 setitimer系统调用

    linux中的alarm和 setitimer系统调用 (2013-07-09 14:30:22) 标签: linuxc编程 alarm signal 文化 alarm和 setitimer系统调用 ...

  3. linux定时执行python脚本_linux定时执行python脚本的方法以及失败不执行的处理方法...

    首页,linux定时任务用到的是crontab,我们来看一下crontab如何使用 crontab-1[user]-列出用户目前的crontab. crontab-e[user]-编辑用户目前的cro ...

  4. Linux定时备份数据到百度云盘

    导读:如今的百度云盘免费容量都是2T了,即使把电脑上所有的东东都放上去,也还有大把的剩余空间.对于站长来说,是完全可以充分利用这些硬盘空间的,现在我们就用百度云盘来备份Linux服务器上的数据.一直在 ...

  5. 空服务器安装linux,debian服务器linux服务器web建站搭建linux服务器之Debian安装

    debian服务器linux服务器web建站搭建linux服务器之Debian安装 原文来自i火吧 大家都知道linux的发行版本很多,有centos啊,debian啊,ubuntu等,下面我就用de ...

  6. 百度网盘自动备份php,Linux定时备份数据到百度云盘

    导读:如今的百度云盘免费容量都是2T了,即使把电脑上所有的东东都放上去,也还有大把的剩余空间.对于站长来说,是完全可以充分利用这些硬盘空间的,现在我们就用百度云盘来备份Linux服务器上的数据. 一直 ...

  7. Linux 定时执行shell 脚本

    2019年第 85 篇文章,总第 109 篇文章 本文大约2000字,阅读大约需要6分钟 crontab 可以在指定的时间执行一个shell脚本以及执行一系列 Linux 命令. 定时执行shell ...

  8. Linux定时备份Oracle Database 翻译

    Linux定时备份Oracle Database 翻译 1. 创建备份文件 vi bak.sh #!/bin/bash export ORACLE_BASE=/home/server/app expo ...

  9. linux脚本调用db2存储过程,LINUX定时执行含有DB2存储过程的SHELL脚本

    <LINUX定时执行含有DB2存储过程的SHELL脚本>由会员分享,可在线阅读,更多相关<LINUX定时执行含有DB2存储过程的SHELL脚本(6页珍藏版)>请在人人文库网上搜 ...

最新文章

  1. PXE网络无人职守安装
  2. .net内存回收与Dispose﹐Close﹐Finalize方法
  3. 对信号与系统课程的意见与建议
  4. 数据对智慧城市建设 起到极大作用
  5. C++(九)——职工信息管理系统
  6. python如何使用图片做背景_用Python批量给照片换底色,基于opencv模块
  7. 我的4条产品设计工作观
  8. ASP.NET MVC 5 学习教程:控制器传递数据给视图
  9. 模板:Prime最小生成树堆优化 + Dijkstra单源最短路堆优化
  10. Putty(菩提)远程连接服务器教程
  11. ARM CORTEX-M0 权威指南 英文
  12. Fabric1.4源码解析:Peer节点启动过程
  13. innoDB索引使用和优化汇总
  14. 没有找到MSVCP80D.dll,因此这个应用程序未能启动。重新安装应用程序...
  15. 厉害了!如何在 Gihub 快速搜索开源项目?
  16. Atitit 文档资料管理同步解决方案
  17. 又一次全球第一!| 凌云时刻
  18. 领导周末喊程序员修bug,程序员霸气回应:在下卖艺不是卖身!
  19. 用计算机做课文成音乐,用计算机音乐制作手机铃声的理论与实践.pdf
  20. 解决win7 中powershell挖矿占用CPU100%

热门文章

  1. 计算机系统基础实验:二进制拆弹实验
  2. 地震勘探原理(二)之时距曲线
  3. 语义分割:遥感影像标签制作
  4. 【文献阅读2020】 像素级自适应学习的超分辨率Pixel-Level Self-Paced Learning For Super-Resolution
  5. 广工数据结构课设——校园导游咨询(C语言)
  6. 【正则】包含大写小写字母数字的8到16位的密码正则
  7. ATP 系列无线测温集中采集触摸屏
  8. High Version Count Issues
  9. iPhone 蓝牙通信编程初步(网上收集)
  10. Tmux Cheat Sheet