免费注册 查看新帖 |

Chinaunix

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

关于sigsetjmp的问题,APUE [复制链接]

论坛徽章:
1
亥猪
日期:2013-10-30 23:29:55
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-30 13:09 |只看该作者 |倒序浏览
本帖最后由 suanmeilizhi 于 2011-12-30 13:40 编辑

程序结构是这样的,在main中首先打印当前信号屏蔽字(pr_mask的作用),然后保存当前环境,等待信号,进程收到信号之后,执行sig_usr1函数,当前的信号被自动加入到信号屏蔽字,所以再次打印的时候应该能看到SIGUSR1(而实际却没有),在信号处理函数sig_usr1中再处理SIGALRM的信号处理函数,同样打印信号屏蔽字,此时的内容应该为SIGUSR1和SIGALRM,然后依次返回,最后在main中,信号屏蔽字应该为空了,但是程序执行时没有任何实际输出。
上代码:
  1. #include "apue.h"
  2. #include <unistd.h>
  3. #include <setjmp.h>
  4. #include <time.h>
  5. #include <errno.h>

  6. static void sig_usr1(int), sig_alrm(int);
  7. static sigjmp_buf jmpbuf;
  8. static volatile sig_atomic_t canjmp;

  9. int
  10. main(void)
  11. {
  12.         if(signal(SIGUSR1, sig_usr1) == SIG_ERR)
  13.           err_sys("signal(SIGUSR1) error");
  14.         if(signal(SIGALRM, sig_alrm) == SIG_ERR)
  15.           err_sys("signal(SIGALRM) error");
  16.         //打印当前被屏蔽的信号
  17.         pr_mask("Starting main: ");
  18.         if(sigsetjmp(jmpbuf, 1)) {
  19.                 pr_mask("End main: ");
  20.                 exit(0);
  21.         }
  22.         canjmp = 1;                //保证sigsetjmp完成之前不会调用siglongjmp
  23.         raise(SIGUSR1);
  24. }

  25. static void
  26. sig_usr1(int signo)
  27. {
  28.         time_t starttime;

  29.         if(canjmp == 0) {
  30.                 return;
  31.         }
  32.         //当前信号被自动加入到进程的信号屏蔽字中,所以此处应该打印  starting sig_usr1: SIGUSR1
  33.         [color=Red]pr_mask("starting sig_usr1: ");                      //(1)[/color]
  34.         alarm(3);
  35.         starttime = time(NULL);
  36.         for(;;)
  37.           if(time(NULL) > starttime + 5)
  38.                 break;
  39.         [color=Red]pr_mask("finishing sig_usr1: ");                   //(2)[/color]
  40.         canjmp = 0;
  41.         siglongjmp(jmpbuf, 1);
  42. }

  43. static void
  44. sig_alrm(int signo)
  45. {
  46.         [color=Red]pr_mask("in sig_arlm: ");                            //(3)[/color]
  47. }

  48. void
  49. pr_mask(const char *str)
  50. {
  51.         sigset_t        sigset;
  52.         int                        errno_save;

  53.         errno_save = errno;               
  54.         if (sigprocmask(0, NULL, &sigset) < 0)
  55.           err_sys("sigprocmask error");

  56.         printf("%s", str);
  57.         if (sigismember(&sigset, SIGUSR1))  printf("SIGUSR1 ");
  58.         if (sigismember(&sigset, SIGALRM))  printf("SIGALRM ");

  59.         printf("\n");
  60.         errno = errno_save;
  61. }
复制代码
在代码中标出了(1)(2)(3),这三处都应该有打印结果,但是实际结果确实这样:
  1. $ ./a.out
  2. Starting main:
  3. starting sig_usr1:
  4. in sig_arlm:
  5. finishing sig_usr1:
  6. End main:
复制代码
按书照抄一遍也有错,不知道为什么???
环境:
Linux ubuntu 2.6.32-34-generic #77-Ubuntu SMP Tue Sep 13 19:40:53 UTC 2011 i686 GNU/Linux

论坛徽章:
0
2 [报告]
发表于 2011-12-30 13:36 |只看该作者
个人看法:
程序设计得好的话完全可以避免使用setjump()/longjump()之类的api
非常熟悉栈,函数调用过程的话就会自然而然地去避免这些导致代码混乱的api

论坛徽章:
1
亥猪
日期:2013-10-30 23:29:55
3 [报告]
发表于 2011-12-30 13:43 |只看该作者
回复 2# garyv


    恩,谢谢你的回复。因为我在看Unix环境高级编程这本书,并且个人水平还没有到那个高度,所以只能抄一遍书上的代码,但是结果却大为不同,所以上来求教。

论坛徽章:
1
亥猪
日期:2013-10-30 23:29:55
4 [报告]
发表于 2011-12-30 13:53 |只看该作者
问题解决了,可能是头文件冲突

论坛徽章:
14
水瓶座
日期:2014-06-10 09:51:0215-16赛季CBA联赛之江苏
日期:2017-11-27 11:42:3515-16赛季CBA联赛之八一
日期:2017-04-12 14:26:2815-16赛季CBA联赛之吉林
日期:2016-08-20 10:43:1215-16赛季CBA联赛之广夏
日期:2016-06-23 09:53:58程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-09 06:20:0015-16赛季CBA联赛之上海
日期:2015-12-25 16:40:3515-16赛季CBA联赛之广夏
日期:2015-12-22 09:39:36程序设计版块每日发帖之星
日期:2015-08-24 06:20:002015亚冠之德黑兰石油
日期:2015-08-07 09:57:302015年辞旧岁徽章
日期:2015-03-03 16:54:15
5 [报告]
发表于 2011-12-30 18:13 |只看该作者
这...头文件中的函数替代了标准库的函数?{:3_189:}

论坛徽章:
1
亥猪
日期:2013-10-30 23:29:55
6 [报告]
发表于 2011-12-30 19:36 |只看该作者
回复 5# lxyscls


    没有,具体情况我也不清楚, "apue.h"头文件里面已经声明了pr_mask函数,并且在别处定义的。而我在自己的代码里面又加了一遍,结果没有输出。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP