linux - 为什么信号没有被屏蔽?

标签 linux signals

当我在 SIGUSR1 处理程序中引发 SIGUSR2 时,它不应该被阻止吗?此代码打印“second - Inside first”

void
hand1(int s) {
    kill(getpid(), SIGUSR2);
    printf("Inside first");
}

void
hand2(int s) {
    printf("second - ");
}

main() {
    signal(SIGUSR1, hand1);
    signal(SIGUSR2, hand2);
    kill(getpid(), SIGUSR1);
}

最佳答案

When I raise SIGUSR2 inside the SIGUSR1 handler, shouldn't it get blocked ?

没有。这是正在发生的事情:

time  signal_mask  code
----  -----------  ----
 0         -       main:signal(SIGUSR1, hand1)
 1         -       main:signal(SIGUSR2, hand1)
 2         -       main:kill(getpid(), SIGUSR1)
 3    USR1         hand1:kill(getpid(), SIGUSR2)
 4    USR1|USR2    hand2:printf("second - ")
 5    USR1         hand1:printf("Inside first")
 6         -       main:...

但是don't use signal(), instead prefer sigaction() .前者不能保证所有平台上的处理程序语义,后者可以。

此外,sigaction 明确了哪些信号在处理程序期间被阻止,哪些不被阻止。如果你想在你的处理程序期间阻止所有信号(我通常建议这样做,因为它更容易推断你知道不会被中断的函数的行为),你可以这样做:

int handle_signal(int sig, void (*handler)(int)) {
  struct sigaction sa = { .sa_flags = 0 };

  sigfillset(&sa.sa_mask); // block everything during handler
  sa.sa_handler = handler;

  return sigaction(sig, &sa, NULL);
}

关于linux - 为什么信号没有被屏蔽?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29033397/

相关文章:

可以成功捕获 CTRL-Z,但不能捕获 SIGTSTP

linux - 为什么 Linux accept() 不返回 EINTR?

linux - 什么是零信号?

linux - cgo (for darwin) 的交叉编译失败

linux - 如何让 nmap 不记录已关闭的主机?

java - 当我当前的工作目录不是默认包时,如何编译文件?

linux - 检测文件何时在 bash 中打开

ruby - 使用 openssl 重新编译/重新安装 Ruby 2.0

c++ - 为什么 SIGSEGV 的信号处理程序无法捕获我的 C++ 抛出异常?

python - 如果忽略 SIGCHLD,Firefox Webdriver 将无法工作