4

我目前正在使用 kqueue 来处理 Serverprocess 中每个线程的多个客户端,因此我不希望在 Signal 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);

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

4

2 回答 2

3

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

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在调用 send 时发出标志。这将抑制 的生成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 */
    }
}
于 2013-07-16T19:24:28.277 回答
1

“信号(...”代码应该在“主”中。

于 2013-11-15T08:16:51.523 回答