免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1959 | 回复: 3
打印 上一主题 下一主题

[C] 使用setjmp后alarm怎么没反应了。。。 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-04-04 16:02 |只看该作者 |倒序浏览
  1. #include <unistd.h>
  2. #include <stdlib.h>
  3. #include <signal.h>
  4. #include <stdio.h>
  5. #include <time.h>
  6. #include <setjmp.h>

  7. typedef void (*Handler)(int);

  8. static jmp_buf env_alrm;

  9. static void pr_time()
  10. {
  11.         time_t now;
  12.         time(&now);
  13.         printf("current timestamp:%ld\n",now);
  14. }

  15. static void sig_alrm(int signo)
  16. {
  17.         printf("received signal.\n");
  18.         longjmp(env_alrm,1);
  19. }

  20. unsigned int sleep1(unsigned int nsecs)
  21. {
  22.         volatile Handler handler;
  23.         volatile int left_sec;
  24.         if((left_sec=alarm(0))<nsecs)
  25.         {
  26.                 return(alarm(left_sec));
  27.         }

  28.         if ((handler=signal(SIGALRM,sig_alrm))==SIG_ERR)
  29.         {
  30.                 return(nsecs);
  31.         }
  32.         left_sec=left_sec-nsecs;
  33.         if(setjmp(env_alrm)==0)
  34.         {
  35.                 alarm(nsecs);
  36.                 //这里如果有竞争条件怎么办,会导致信号丢失的。。
  37.                 printf("wating to wake up from pause\n");
  38.                 pause();//休眠
  39.         }
  40.         if(signal(SIGALRM,handler)==SIG_ERR)
  41.         {
  42.                 printf("recover error.\n");
  43.         }
  44.         printf("left_sec:%d\n",left_sec);
  45.         return(alarm(left_sec));
  46. }

  47. int main(void)
  48. {
  49.         alarm(5);
  50.         pr_time();
  51.         sleep1(3);
  52.         pr_time();
  53.         printf("i am here.\n");
  54.         pause();
  55.         exit(0);
  56. }
复制代码
模拟sleep函数,当不使用setjmp的时候,代码能正确运行,当使用的setjmp的时候,alarm好像没反应了。。。
求指导啊。。。。

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
2 [报告]
发表于 2013-04-04 16:48 |只看该作者
没看楼主的场景,

1, siglongjmp防止阻塞被信号处理函数block的信号.
2, sigprocmask + sigsuspend 不会用的话就必须学一下了, 和pthread_mutex_lock, pthread_cond_wait是一样的道理.

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
3 [报告]
发表于 2013-04-04 17:24 |只看该作者
首先,你要想明白两种运行环境。
1. 线程的运行环境
2. 信号处理函数的运行环境

环境1可以被中断,跳转入环境2。
环境2运行完,再回到环境1。

环境2不能够被再次中断,进入环境2。否则信号一多,stack就溢出了。

其次,longjump只是包存恢复寄存器而已。不会改变运行环境。

论坛徽章:
0
4 [报告]
发表于 2013-04-04 18:18 |只看该作者
linux_c_py_php 发表于 2013-04-04 16:48
没看楼主的场景,

1, siglongjmp防止阻塞被信号处理函数block的信号.

刚才看到信号屏蔽字的时候,才发现原来在信号处理函数里面,longjmp导致当前信号被自动加到进程的信号屏蔽字当中了。。。。。恢复了下进程屏蔽字程序就正常了。。。。。。跟你说的是同一回事。嘿嘿!!!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP