在哪里为 SIGPIPE 声明 sig_t 信号

Posted

技术标签:

【中文标题】在哪里为 SIGPIPE 声明 sig_t 信号【英文标题】:Where to declare sig_t signal for SIGPIPE 【发布时间】:2013-07-16 16:43:37 【问题描述】:

我目前正在使用 kqueue 来处理服务器进程中每个线程的多个客户端 所以我不希望在出现信号 SIGPIPE 时终止线程,我只想从 kqueue 中删除相应的 socked id。 所以我的问题是:有没有办法在 Signalhandle 中获取相应的 socketid 并将其解析回进程以将其从事件 kqueue 中删除,或者我是否需要 SIG_IGN SIGPIPE 并通过从发送返回 -1 来处理删除?它会在超时时间后返回 -1 值还是立即返回 send -1?

最后,如果信号忽略是我的解决方案:id 的声明必须放在哪里

typedef void (*sig_t) (int);
 sig_t
 signal(int sig, sig_t func);

它必须在主函数中吗? 还是在相应线程的开头?还是作为全局元素?

【问题讨论】:

send() 的结果做出反应至少更便携,所以对我来说这似乎是更好的方法。无论如何,我很好奇是否有人有答案(+1)。 好吧,也许我又把我的问题表达得很糟糕了,但就我打算使用 send() 的返回而言,我只是想知道,我必须把 sig_t 信号(SIGPIPE,SIG_IGN)放在哪里;让信号被忽略。 【参考方案1】:

我想不出一种简单的方法让信号处理程序知道当前正在处理的套接字,除非您在每次执行套接字操作时都设置一些全局状态。

您可以从 main 中忽略 SIGPIPE。您没有定义自己的处理程序,而是使用SIG_IGN

signal(SIGPIPE, SIG_IGN);

或者,如果您使用的是sigaction

struct sigaction act;
act.sa_handler = SIG_IGN;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGPIPE, &act, NULL); 

或者,您可以在调用 send 时发出 MSG_NOSIGNAL 标志。这将抑制SIGPIPE 的生成,而是生成EPIPE 错误(如果您忽略SIGPIPE 会发生这种情况):

ssize_t sent = send(sock, buf, sizeof(buf), MSG_NOSIGNAL);
if (sent > 0) 
    /* ... */
 else 
    assert(sent < 0);
    swtich (errno) 
    case EPIPE:
        /* ...handle sending on a closed socket */
    /* ...handle other error cases */
    

【讨论】:

【参考方案2】:

'signal(...' 代码应该在'main'中。

【讨论】:

这没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方发表评论 - 您可以随时评论自己的帖子,一旦您有足够的reputation,您就可以comment on any post。 @jpw 嗯,它根本没有得到很好的解释,这是真的,但它为我的问题提供了一个答案(即使它不是一个好的问题,它也是一个(正确和)说明性的答案。

以上是关于在哪里为 SIGPIPE 声明 sig_t 信号的主要内容,如果未能解决你的问题,请参考以下文章

sigpipe c server/client - 程序在哪里重新启动?

如何让MAC屏蔽SIGPIPE信号?

忽略SIGPIPE信号

SIGPIPE 13 和其他信号的对照表

什么信号(SIGPIPE,SIG_IGN);做?

避免SIGPIPE导致的iOS应用闪退/Avoiding SIGPIPE signal crash in iOS(mach_msg_trapSIGPIPE信号)