2013-07-16 49 views
4

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

最后,如果信号忽略的是我的解决方案:其中id必须把的

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

声明难道必须要在主函数? 还是在相应的线程开头?或仅仅是全球元素?

+0

对send()的结果做出反应至少是更便携的,所以对我来说似乎是更好的方式。无论如何,我很好奇,如果有人有答案(+1) –

+0

好吧,也许我表达了我的问题再次坏了,但尽可能使用返回的send(),我只是想知道,在哪里我必须把sig_t信号(SIGPIPE,SIG_IGN);让信号被忽略 – dhein

回答

3

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

您可以忽略来自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); 

或者,当你打电话给你可以发出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 */ 
    } 
} 
1

“信号(...”代码应该是“主”

+0

这不提供回答这个问题。要批评或要求作者澄清,在他们的帖子下留下评论 - 你总是可以评论你自己的帖子,一旦你有足够的[声誉](http://stackoverflow.com/help/whats-reputation),你会能够[评论任何帖子](http://stackoverflow.com/help/privileges/comment)。 – jpw

+0

@jpw好吧,它没有得到很好的解释,这是真的,但它提供了我的问题的答案(即使它不是一个好的答案,它是一个(正确的)说明性的答案。 – dhein