免费注册 查看新帖 |

Chinaunix

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

sigsuspend的疑惑,请指教 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-01-21 10:01 |只看该作者 |倒序浏览
这是APUE中一段代码(Program 10.15):

  1. #include        <signal.h>;
  2. #include        "ourhdr.h"

  3. static void        sig_int(int);

  4. int
  5. main(void)
  6. {
  7.         sigset_t        newmask, oldmask, zeromask;

  8.         if (signal(SIGINT, sig_int) == SIG_ERR)
  9.                 err_sys("signal(SIGINT) error");

  10.         sigemptyset(&zeromask);

  11.         sigemptyset(&newmask);
  12.         sigaddset(&newmask, SIGINT);
  13.                                         /* block SIGINT and save current signal mask */
  14.         if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
  15.                 err_sys("SIG_BLOCK error");

  16.                                         /* critical region of code */
  17.         pr_mask("in critical region: ");

  18.                                         /* allow all signals and pause */
  19.         if (sigsuspend(&zeromask) != -1)
  20.                 err_sys("sigsuspend error");
  21.         pr_mask("after return from sigsuspend: ");

  22.                                         /* reset signal mask which unblocks SIGINT */
  23.         if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
  24.                 err_sys("SIG_SETMASK error");

  25.                                         /* and continue processing ... */
  26.         exit(0);
  27. }

  28. static void
  29. sig_int(int signo)
  30. {
  31.         pr_mask("\nin sig_int: ");
  32.         return;
  33. }
复制代码



  1. 运行结果:
  2. $a.out
  3. in critical region: SIGINT
  4. ^C
  5. /*sigsuspend还没有返回,为什么执行sig_int时,signal masks中有 SIGINT? 第一次不知道是怎么想的,当时觉得是对的, 现在觉得执行sig_int时,signal masks 应还是zeromask的值 */
  6. in sig_int: SIGINT
  7. after return from sigsuspend: SIGINT
复制代码

论坛徽章:
0
2 [报告]
发表于 2005-01-21 10:14 |只看该作者

sigsuspend的疑惑,请指教

>;>; 现在觉得执行sig_int时,signal masks 应还是zeromask的值
就是这样啊,不然^C怎么可能进入中断信号处理程序呢?

论坛徽章:
0
3 [报告]
发表于 2005-01-21 11:02 |只看该作者

sigsuspend的疑惑,请指教

但是转入sig_int程序时,sigsuspend还没有返回,
所以
static void
sig_int(int signo)
{
   pr_mask("\nin sig_int: ";
   return;
}
打出的signal masks应该没有SIGINT才对吧

论坛徽章:
0
4 [报告]
发表于 2005-01-21 11:15 |只看该作者

sigsuspend的疑惑,请指教

〉〉但是转入sig_int程序时,sigsuspend还没有返回
我没有找到pr_mask的源码,我想作者的意思是打印被sigsuspend解除阻塞的信号,而不是当前正被阻塞的信号

论坛徽章:
0
5 [报告]
发表于 2005-01-21 11:27 |只看该作者

sigsuspend的疑惑,请指教

你等等,我把源码打出来。

论坛徽章:
0
6 [报告]
发表于 2005-01-21 11:28 |只看该作者

sigsuspend的疑惑,请指教

不好意思,我上面说错了

〉〉但是转入sig_int程序时,sigsuspend还没有返回
调用sig_int的时候sigsuspend已经返回,它重新将进程信号屏蔽字设为sigint
这样也不对呀?   

论坛徽章:
0
7 [报告]
发表于 2005-01-21 11:30 |只看该作者

sigsuspend的疑惑,请指教


  1. #include        <errno.h>;
  2. #include        <signal.h>;
  3. #include        "ourhdr.h"

  4. void
  5. pr_mask(const char *str)
  6. {
  7.         sigset_t        sigset;
  8.         int                        errno_save;

  9.         /* we can be called by signal handlers */
  10.         errno_save = errno;               
  11.         if (sigprocmask(0, NULL, &sigset) < 0)
  12.                 err_sys("sigprocmask error");

  13.         printf("%s", str);
  14.         if (sigismember(&sigset, SIGINT))        printf("SIGINT ");
  15.         if (sigismember(&sigset, SIGQUIT))        printf("SIGQUIT ");
  16.         if (sigismember(&sigset, SIGUSR1))        printf("SIGUSR1 ");
  17.         if (sigismember(&sigset, SIGALRM))        printf("SIGALRM ");
  18.                 /* remaining signals can go here */
  19.         printf("\n");
  20.         errno = errno_save;
  21. }
复制代码

从pr_mask的代码来看, 它只是打印进程当前的signal masks,在sigsuspend没返回时, 应该是zeromask的值才对

论坛徽章:
0
8 [报告]
发表于 2005-01-21 11:37 |只看该作者

sigsuspend的疑惑,请指教

原帖由 "lisp" 发表:
不好意思,我上面说错了

〉〉但是转入sig_int程序时,sigsuspend还没有返回
调用sig_int的时候sigsuspend已经返回,它重新将进程信号屏蔽字设为sigint


应该是sig_int返回后sigsuspend才返回的, 以下是APUE的原话:

   If a signal is caught and if the signal handler returns, then sigsuspend returns and the signal mask of the process is set to its value before the call to sigsuspend.

论坛徽章:
0
9 [报告]
发表于 2005-01-21 11:45 |只看该作者

sigsuspend的疑惑,请指教

1。初始SIGINT被屏蔽
2。执行sigsuspend将屏蔽字设为zeromask,sigsuspend阻塞(原子操作)
3。^C发出SIGINT信号,因为此时进程屏蔽字为zeromask,所以进程收到信号,但并未调用sig_int(注1)。
4。sigsuspend返回,重新将信号屏蔽字设为SIGINT
5。主线程被sig_int抢占,但此时信号屏蔽子已经设为了SIGINT,所以打印信息中有SIGINT
注1:为什么此时sig_int未被调用?因为sigsuspend位于内核态执行不能被能被抢占
这样好像说得通,你看呢?

论坛徽章:
0
10 [报告]
发表于 2005-01-21 12:35 |只看该作者

sigsuspend的疑惑,请指教

[quote]原帖由 "lisp" 发表:
1。初始SIGINT被屏蔽
2。执行sigsuspend将屏蔽字设为zeromask,sigsuspend阻塞(原子操作)
3。^C发出SIGINT信号,因为此时进程屏蔽字为zeromask,所以进程收到信号,但并未调用sig_int(注1)。
4。sigsuspend返
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP