2013-07-16 41 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