C:signal()是进程级吗?

C:signal()是进程级吗?,c,linux,multithreading,C,Linux,Multithreading,我正在用C编写一个小型web服务器,我想忽略SIGPIPE信号,这样我的服务器就不会因为试图写入关闭的连接而终止 信号(信号管、信号灯) 我创建线程来处理每个请求,并在主线程设置忽略信号但我认为信号是进程级的,所以我相信这应该适用于创建的任何子线程。(即,我不必在子线程中再次调用此信号忽略。)但是,我的服务器仍将因某种原因终止。我仍在调试,但我只想确保这不是SIGPIPE问题….从技术上说,在多线程环境中使用signal函数会导致未定义的行为(这很疯狂,IMHO,特别是如果您使用SIG\u IG

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

信号(信号管、信号灯)

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

从技术上说,在多线程环境中使用signal函数会导致未定义的行为(这很疯狂,IMHO,特别是如果您使用
SIG\u IGN
调用它)

实际上,信号处理是进程范围的,建议新的POSIX程序使用
sigaction
而不是
signal
,因为
sigaction
具有更好的语义定义(这与
SIG\u IGN
无关)

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

sigaction(SIGPIPE, &(struct sigaction){ .sa_handler = SIG_IGN }, 0);
(请注意,如果调用正确,则不必检查返回状态,因为唯一可能出现的错误是a,即
EINVAL
EFAULT
,只有在提供格式错误的参数时才会出现),表示在多线程环境中使用signal函数会导致未定义的行为(这很疯狂,IMHO,尤其是当您使用
SIG\u IGN
调用它时)

实际上,信号处理是进程范围的,建议新的POSIX程序使用
sigaction
而不是
signal
,因为
sigaction
具有更好的语义定义(这与
SIG\u IGN
无关)

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

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

(请注意,如果正确调用它,则不必检查返回状态,因为唯一可能出现的错误是a,即
EINVAL
EFAULT
,只有在提供格式错误的参数时才会出现这些错误。)

如果正确,这将忽略进程所有线程上的SIGPIPE。如果正确,这将忽略进程所有线程上的SIGPIPE。@Dolda2000如果标准人员至少能够区分“这可能会破坏代码生成;不要这样做”和“这可能不会很好地发挥您的运行时;检查您的系统手册和/或适用于它的标准”,那就太好了,但这可能要求太多了。清楚地多次提到线程。例如:每个线程都有一个“信号掩码”,它定义了当前阻止传递给它的一组信号。线程的信号掩码应从其父线程或创建线程的信号掩码初始化,如果该线程是调用fork()创建的,则应从父进程中相应的线程初始化。pthread_sigmask()、sigaction()、sigprocmask()和sigssuspend()函数控制信号掩码的操作。此外,只有在提供格式错误的参数时,才会得到信号掩码?因此,如果你不检查错误,你怎么知道你是否错误地提供了格式错误的参数?@AndrewHenle,C标准说它是未定义的。POSIX清楚地定义了它。@Dolda2000如果标准人员至少能够区分“这可能会破坏代码生成;不要这样做”和“这可能会影响您的运行时;检查您的系统手册和/或适用于它的标准”,那就太好了,但这可能要求太多了。清楚地多次提到线程。例如:每个线程都有一个“信号掩码”,它定义了当前阻止传递给它的一组信号。线程的信号掩码应从其父线程或创建线程的信号掩码初始化,如果该线程是调用fork()创建的,则应从父进程中相应的线程初始化。pthread_sigmask()、sigaction()、sigprocmask()和sigssuspend()函数控制信号掩码的操作。此外,只有在提供格式错误的参数时,才会得到信号掩码?因此,如果你不检查错误,你怎么知道你是否错误地提供了格式错误的参数?@AndrewHenle,C标准说它是未定义的。POSIX清楚地定义了它。