C语言 替换SIGUSR1信号处理程序在标准 C11 和 GNU11 中的工作方式不同



我想覆盖SIGUSR1信号处理程序的行为。但是使用不同的C标准我得到了不同的结果。如果我使用 C11 标准,我的信号处理程序在收到此信号一次后会替换为默认信号。因此,如果我将信号SIGUSR1发送到进程两次,那么第二次,将调用默认的SIGUSR1处理程序而不是我的处理程序。但是在 GNU11 标准中,每次都调用我的。如何使用 C11 标准获得此行为?

这是我的代码:

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
void noop(int signo)
{
(void) signo;
}
int main(int argc, char **argv)
{
(void) argc; (void) argv;
if (signal(SIGUSR1, noop) == SIG_ERR)
{
perror("Can't register handler for signal SIGUSR1");
exit(EXIT_FAILURE);
}
while (1);
}

使用 C11 标准编译此程序:

gcc signal.c -o signal_c11.out -std=c11 -O0 -Wall -Wextra -Wpedantic
./signal_c11.out

或者用 GNU11 标准编译这个程序:

gcc signal.c -o signal_gnu11.out -std=gnu11 -O0 -Wall -Wextra -Wpedantic
./signal_gnu11.out

在另一个终端中,执行

kill -s SIGUSR1 <pid-of-above-process>
kill -s SIGUSR1 <pid-of-above-process>

然后,来自程序 signal_c11.out 的进程将根据SIGUSR1信号的默认操作终止;但来自程序 signal_gnu11.out 的进程将继续运行,这是我所期望的。

如何使用 c11 标准获得 gnu11 行为?

基于某些功能测试宏定义在 System V 和 BSD 语义之间更改signal()行为(请参阅该手册页上的可移植性(。

在这种情况下,主要区别在于 System Vsignal()调用处理程序时自动重置处理程序,而 BSD 不会。

使用sigaction()您可以设置预期的行为(不设置SA_RESETHAND标志,可能设置SA_RESTART标志(。

正如signal()手册页所说:

signal(( 的行为因 UNIX 版本而异,并且还具有 历史上不同版本的 Linux 各不相同。 避免其 使用:改用 sigaction(2(。

-D_DEFAULT_SOURCE传递给gcc。如果未启用严格的标准一致性(即没有-std=c*选项(,则隐式定义此标志。

这将获得从 gnu11 到 c11 的所有与 C 库相关的内容。但是,它不会获得任何语法内容,例如typeof或其他语法。

相关内容

  • 没有找到相关文章

最新更新