在哪里为SIGPIPE声明sig_t信号

时间:2013-07-16 16:43:37

标签: c sockets signals kqueue

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

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

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

是否必须在主要功能中? 还是在相应线程的开头?还是作为全球元素?

2 个答案:

答案 0 :(得分: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 :(得分:1)

'信号(......'代码应该在'main'。