【问题标题】:sigprocmask() issuesigprocmask() 问题
【发布时间】:2011-04-16 18:27:02
【问题描述】:

以下代码来自unix 环境中的高级编程一书,W. Richard Stevens

关于这本密码书说;

“如果信号在被阻塞时被发送到进程,信号传递将被推迟到信号被解除阻塞。对于应用程序来说,这看起来好像信号发生在解除阻塞和暂停之间(取决于内核如何实现信号)。如果发生这种情况,或者如果信号确实发生在解除阻塞和暂停之间,我们就有问题了。在这个时间窗口中任何出现的信号都会丢失,因为我们可能看不到再次发出信号,这种情况下暂停将无限期阻塞。这是早期不可靠信号的另一个问题。”

它建议在重置信号掩码之前使用sigsuspend() 而不是pause(),因为它会重置信号掩码并使进程在单个原子操作中进入睡眠状态。但我不希望我的过程等到退出关键区域后出现信号。 那么这个问题对我的情况也有效吗?如果是这样,在使用sigprocmask() 重置信号掩码时我应该使用什么来不丢失信号?

 sigset_t     newmask, oldmask;

  sigemptyset(&newmask);
  sigaddset(&newmask, SIGINT);

  /* block SIGINT and save current signal mask */
  if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
      err_sys("SIG_BLOCK error");

  /* critical region of code */

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

  /* window is open */
  pause();  /* wait for signal to occur */

  /* continue processing */

【问题讨论】:

  • 你还没有真正弄清楚你的问题是什么。你有一个关键的代码区域吗?你的情况是什么?
  • 我的代码与上面的代码类似,没有 pause() 但其他我自己的功能。在两个 sigprocmask() 调用之间是我的关键区域,如上面的代码,但在我的情况下,上面的所有代码都在 while(1) 循环中。所以我希望我的信号处理程序在程序执行超出临界区并且如果信号(它是一个 SIGALRM)被传递时工作。
  • 您可以在调用 sigprocmask() 解锁信号之前使用 sigpending() 来查找挂起的信号,但这似乎有点矫枉过正。

标签: c linux signals


【解决方案1】:

sigsuspend 用于避免 sigprocmask 和暂停之间的过程。如果您在收到信号之前不需要暂停线程,那么 sigsuspend 无能为力。您没有提供足够的信息来了解您的上下文中是否存在其他问题来源。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-24
    • 2016-02-08
    • 2010-09-06
    • 2011-01-11
    • 1970-01-01
    • 2018-10-16
    • 2011-11-02
    • 2023-03-09
    相关资源
    最近更新 更多