alarm闹钟





alarm闹钟

alarm闹钟

信号


alarm理解

  
  
  1. #include <unistd.h>
  2. unsigned int alarm(unsigned int seconds)
  3. // 返回值 : 0 或者 剩余的时间. 如果在seconds秒内再次调用了alarm函数设置了新的闹钟,则后面定时器的设置将覆盖前面的设置,即之前设置的秒数被新的闹钟时间取代;当参数seconds为0时,之前设置的定时器闹钟将被取消,并将剩下的时间返回。

alarm函数可以设置一个定时器, 在将来的某个时刻调用.
每个程序只能有一个闹钟时间, 当然, 不是指只有一个alarm()函数调用.

  
  
  1. /*************************************************************************
  2. > File Name: alarm_test_1.cpp
  3. > Author: Function_Dou
  4. > Mail:
  5. > Created Time: 2018年03月04日 星期日 16时30分19秒
  6. ************************************************************************/
  7. #include <stdio.h>
  8. #include <unistd.h>
  9. #include <stdlib.h>
  10. #include <signal.h>
  11. static void sig_alarm(int);
  12. int main(void)
  13. {
  14. if(signal(SIGALRM, sig_alarm) == SIG_ERR)
  15. fprintf(stderr, "signal(SIGALRM) error");
  16. alarm(2);
  17. sleep(1);
  18. printf("time out\n");
  19. exit(0);
  20. }
  21. void sig_alarm(int)
  22. {
  23. printf("alarm time out!\n");
  24. exit(0);
  25. }

运行结果

  
  
  1. [root@localhost Signal]# ./a.out
  2. time out

在此可以看出, 调用alarm()函数调用后, 程序会继续执行, 而不会像sleep()一样阻塞. 因为alarm()如果阻塞, 那么当2s过了会调用sig_alarm()函数, 而不是再执行sleep()了.

验证

  
  
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <signal.h>
  5. static void sig_alarm(int);
  6. int main(void)
  7. {
  8. if(signal(SIGALRM, sig_alarm) == SIG_ERR)
  9. fprintf(stderr, "signal(SIGALRM) error");
  10. alarm(2);
  11. printf("hello\n");
  12. sleep(4);
  13. printf("time out\n");
  14. exit(0);
  15. }
  16. void sig_alarm(int)
  17. {
  18. printf("alarm time out!\n");
  19. exit(0);
  20. }

运行结果

  
  
  1. [root@localhost Signal]# ./a.out
  2. hello
  3. alarm time out!

先输出了hello, 然后执行了sleep(), 然而alarm()时间只是2s, 所以2s后触发了sig_alarm()函数, 最后退出, 所以sleep之后的语句就无法执行.

继续验证

  
  
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <signal.h>
  5. static void sig_alarm(int);
  6. int main(void)
  7. {
  8. if(signal(SIGALRM, sig_alarm) == SIG_ERR)
  9. fprintf(stderr, "signal(SIGALRM) error");
  10. alarm(4);
  11. for(int i = 0; ; i++)
  12. {
  13. printf("%d\n", i);
  14. sleep(1);
  15. }
  16. exit(0);
  17. }
  18. void sig_alarm(int)
  19. {
  20. printf("alarm time out!\n");
  21. exit(0);
  22. }

运行结果

  
  
  1. [root@localhost Signal]# ./a.out
  2. 0
  3. 1
  4. 2
  5. 3
  6. alarm time out!

sleep改写

  
  
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <signal.h>
  5. #include <setjmp.h>
  6. static jmp_buf env_jmp;
  7. static void sig_alrm(int)
  8. {
  9. longjmp(env_jmp, 1);
  10. }
  11. unsigned int sleep2(unsigned int seconds)
  12. {
  13. if(signal(SIGALRM, sig_alrm) == SIG_ERR)
  14. return (seconds);
  15. if(setjmp(env_jmp) == 0)
  16. {
  17. alarm(seconds);
  18. // 等待alarm()结束才能往下执行其他的, 进程阻塞
  19. pause();
  20. }
  21. return alarm(0);
  22. }
  23. int main(void)
  24. {
  25. sleep2(2);
  26. exit(0);
  27. }

一个read计时程序

用alarm()定时一个read计时器, 当达到时间后就停止输入, 不一直等待输入.
在shell编程里面, “read -t sec” 表示sec的时间结束输入

  
  
  1. #include <stdio.h>
  2. #include <setjmp.h>
  3. #include "apue.h"
  4. #include <signal.h>
  5. static void sig_alarm(int);
  6. static jmp_buf env_alarm;
  7. int main(void)
  8. {
  9. int n;
  10. char line[MAXLINE];
  11. if(signal(SIGALRM, sig_alarm) == SIG_ERR)
  12. err_sys("signal(SIGALRM) error");
  13. if(setjmp(env_alarm) != 0)
  14. {
  15. err_quit("read timeout");
  16. pause();
  17. }
  18. // 计时, read()时间等待2s
  19. alarm(2);
  20. if((n = read(STDIN_FILENO, line, MAXLINE)) < 0)
  21. err_sys("read error");
  22. // 时间到了, alarm(0)返回0, 时间不到就返回剩余时间.
  23. alarm(0);
  24. write(STDOUT_FILENO, line, n);
  25. exit(0);
  26. }
  27. static void sig_alarm(int)
  28. {
  29. printf("time out\n");
  30. longjmp(env_alarm, 1);
  31. }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值