免费注册 查看新帖 |

Chinaunix

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

关于sigsuspend的理解 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-07-20 16:40 |只看该作者 |倒序浏览
一开始没看明白APUE里的例子,后来google了下搜索到了这篇文章
http://bigwhite.blogbus.com/logs/1453143.html
它讲:

  1. 如果按照sig_handler先返回,那么SIGINT是不该被打印出来的,因为那时屏蔽字还没有恢复,所有信号都是不阻塞的。那么是Stevens说错了么?当然没有,只是Stevens没有说请在sigsuspend的原子操作中到底做了什么?
  2. sigsuspend的整个原子操作过程为:
  3. (1) 设置新的mask阻塞当前进程;
  4. (2) 收到信号,恢复原先mask;
  5. (3) 调用该进程设置的信号处理函数;
  6. (4) 待信号处理函数返回后,sigsuspend返回。
复制代码

里面(2)说的我看不对啊。

这是APUE里的例子

  1. #include "apue.h"

  2. static void    sig_int(int);

  3. int
  4. main(void)
  5. {
  6.     sigset_t    newmask, oldmask, waitmask;

  7.     pr_mask("program start: ");

  8.     if (signal(SIGINT, sig_int) == SIG_ERR)
  9.         err_sys("signal(SIGINT) error");
  10.     sigemptyset(&waitmask);
  11.     sigaddset(&waitmask, SIGUSR1);
  12.     sigemptyset(&newmask);
  13.     sigaddset(&newmask, SIGINT);

  14.     /*
  15.      * Block SIGINT and save current signal mask.
  16.      */
  17.     if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
  18.         err_sys("SIG_BLOCK error");

  19.     /*
  20.      * Critical region of code.
  21.      */
  22.     pr_mask("in critical region: ");

  23.     /*
  24.      * Pause, allowing all signals except SIGUSR1.
  25.      */
  26.     if (sigsuspend(&waitmask) != -1)
  27.         err_sys("sigsuspend error");

  28.     pr_mask("after return from sigsuspend: ");

  29.     /*
  30.      * Reset signal mask which unblocks SIGINT.
  31.      */
  32.     if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
  33.         err_sys("SIG_SETMASK error");

  34.     /*
  35.      * And continue processing ...
  36.      */
  37.     pr_mask("program exit: ");

  38.     exit(0);
  39. }

  40. static void
  41. sig_int(int signo)
  42. {
  43.     pr_mask("\nin sig_int: ");
  44. }
  45. =================================================

  46. 打印出
  47. program start:
  48. in critical region: SIGINT
  49. ^C
  50. in sig_int: SIGINT SIGUSR1
  51. after return from sigsuspend: SIGINT
  52. program exit:
复制代码




照它说的顺序,那么in sig_int里不应该有SIGUSR1啊,因为他讲收到信号(这里是SIGINT),就恢复原来mask(就是SIGINT),那么SIGUSR1不应该出现在sig_int里了。


我个人认为:在调用sigsuspend之前只有SIGINT被阻塞,调用sigsuspend后,信号屏蔽字集被临时替换成SIGUSR1,此时可以递送SIGINT,当SIGINT发生,去执行sig_int,注意:在sig_int里会打出in sig_int: SIGINT SIGUSR1 ,是因为操作系统会自动给正在被递送的信号加入屏蔽字集里,当sig_int返回,sigsuspend也将返回,此时屏蔽字就是SIGINT。

由于此文还被到处转载了,个人对sigsuspend用的不是很多,所以有一点浅见,望高人给我看下,该文章是否解释上有点瑕疵。

论坛徽章:
0
2 [报告]
发表于 2009-07-21 18:13 |只看该作者
光看不回啊

论坛徽章:
0
3 [报告]
发表于 2009-07-25 23:45 |只看该作者
我也没搞清楚。个人觉得信号部分是难掌握的。通常都不会去考虑这些。如果是编写核心的稳固程序的我觉得非常之重要。尤其在很多并行和异步处理的时候。
今天先顶一下,搞清楚了再来。

论坛徽章:
0
4 [报告]
发表于 2009-07-26 09:24 |只看该作者
是的,需要多实践啊。
pcanywhere 该用户已被删除
5 [报告]
发表于 2009-07-27 18:04 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
6 [报告]
发表于 2009-07-27 22:05 |只看该作者
原帖由 bsdc 于 2009-7-20 16:40 发表
我个人认为:在调用sigsuspend之前只有SIGINT被阻塞,调用sigsuspend后,信号屏蔽字集被临时替换成SIGUSR1,此时可以递送SIGINT,当SIGINT发生,去执行sig_int,注意:在sig_int里会打出in sig_int: SIGINT SIGUSR1 ,是因为操作系统会自动给正在被递送的信号加入屏蔽字集里,当sig_int返回,sigsuspend也将返回,此时屏蔽字就是SIGINT。


完全正确,一点问题没有!!!

论坛徽章:
0
7 [报告]
发表于 2009-07-28 11:11 |只看该作者
感谢楼上的几位朋友,呵呵讨论一下增加印象。

论坛徽章:
0
8 [报告]
发表于 2009-07-28 11:22 |只看该作者
你转载的那篇文章跟你的结果不一样啊,是不是平台不同,处理方式不一样?

论坛徽章:
0
9 [报告]
发表于 2009-07-28 14:44 |只看该作者
原帖由 lanying_wzw 于 2009-7-28 11:22 发表
你转载的那篇文章跟你的结果不一样啊,是不是平台不同,处理方式不一样?

是不一样的,但差不多。
我转的那篇 调用sigsuspend是 if (sigsuspend(&zeromask) != -1) ,等于没有设置临时mask。

转它主要是我之前理解不清,看他那篇讲得头头是道,但现在看来是有问题的。

论坛徽章:
0
10 [报告]
发表于 2009-07-28 16:13 |只看该作者
什么差不多啊
你的结果是:in sig_int: SIGINT SIGUSR1
他的结果是:in sig_int: SIGINT
差老鼻子远了,真服你了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP