C: signal() 是进程级别的吗?

Posted

技术标签:

【中文标题】C: signal() 是进程级别的吗?【英文标题】:C: is signal() process-level? 【发布时间】:2017-11-19 22:08:07 【问题描述】:

我正在用 C 语言编写一个小型 Web 服务器,我想忽略 SIGPIPE 信号,这样我的服务器就不会因尝试写入已关闭的连接而终止。

Signal(SIGPIPE, SIG_IGN);

我创建线程来处理每个请求,并在主线程设置信号忽略。 但我认为信号是进程级别的,所以我相信这应该适用于创建的任何子线程。(即,我不必在我的子线程中再次调用此信号忽略。)但仍然,我的服务器将因某种原因终止。我仍在调试,但我只是想确保这不是 SIGPIPE 问题.....

【问题讨论】:

你是对的,这将忽略你进程所有线程上的 SIGPIPE。 【参考方案1】:

从技术上讲,C standard 表示在多线程环境中使用信号函数会导致未定义的行为(这很疯狂,恕我直言,尤其是当您使用 SIG_IGN 调用它时)。

实际上,信号处理是进程范围的,建议新的 POSIX 程序使用sigaction 而不是signal,因为sigaction 具有更好的定义语义(这对SIG_IGN 并不重要)。

在 C99 及更高版本中,您可以像这样调用 sigaction:

sigaction(SIGPIPE, &(struct sigaction) .sa_handler = SIG_IGN , 0);

(请注意,如果您正确调用它,则不必检查返回状态,因为唯一可能的错误 a 是 EINVALEFAULT,只有在您提供 ill-形成的论点。)

【讨论】:

@Dolda2000 如果标准的人至少可以区分“这可能会破坏代码生成;不要这样做”和“这可能无法与您的运行时配合使用;检查您的系统手册和/或适用于它的标准”,但也许这要求太多了。 POSIX Signal Concepts 多次明确提及线程。例如: 每个线程都有一个“信号掩码”,它定义了当前阻止传递给它的一组信号。线程的信号掩码应从其父线程或创建线程的信号掩码初始化,或者如果线程是由于调用 fork() 而创建的,则应从父进程中的相应线程初始化。 pthread_sigmask()、sigaction()、sigprocmask() 和 sigsuspend() 函数控制信号掩码的操作。 另外,只有在提供格式错误的参数时才能得到什么?所以如果你不检查错误,你怎么知道你是否错误地提供了格式错误的参数? @AndrewHenle C 标准说它是未定义的。 POSIX 明确定义了它。

以上是关于C: signal() 是进程级别的吗?的主要内容,如果未能解决你的问题,请参考以下文章

c的signal函数

电路中signal path怎么看

C/C++ 中的结构赋值是原子的吗?

来自标准信号库的 C 声明

python signal(信号)

会的帮做下!