我有一个用C编写的多线程SSL服务器,其行为如下:
epoll
),接受它们并为每个客户端套接字生成一个分离的线程SSL_accept
。成功执行 SSL握手后,线程会从客户端接收消息并回复每条SSL_read
的消息。我尝试模拟并发客户端连接以测试服务器。
在一次此类模拟中,我的服务器退出SIGPIPE
信号。
有没有办法在线程级别捕获和处理SIGPIPE
?我希望相应的线程处理信号,而不是整个进程退出。
最初我尝试signal(SIGPIPE,SIG_IGN)
,但signal(2) man说:
未指定signal()在多线程进程中的影响。
可以使用signalfd来处理此类SIGPIPEs
吗?
还是有其他解决方案吗?
注意:服务器在Ubuntu 12.04上运行,我无法在MSG_NOSIGNAL
上使用send
,因为我直接使用OpenSSL作为库(无源代码)
提前致谢。
答案 0 :(得分:5)
有没有办法在线程级别捕获和处理SIGPIPE?我希望相应的线程处理信号,而不是整个进程退出。
是的,有。您需要阻止除一个线程之外的所有线程中的信号(在创建任何线程之前最好这样做)。如果你正在使用pthreads,你可以使用pthread_sigmask
,因为这将保证,在调用它之后,每个创建的线程都将继承信号掩码。然后在一个特定的线程中,您需要使用signal
注册一个处理程序(不要使用sigaction
,它已过时)。
当信号到达你的进程时,它将被阻塞,直到这一个线程将继续它的进程工作(只有那时信号被进程接收,这就是为什么它是未指定的行为 - 它取决于正在运行的线程,但通过阻塞信号在你指定哪一个可以对它作出反应的所有其他线程上。)
其他方式:
如果你想永远不接收这个信号,并且知道哪个套接字被破坏了,你只能使用pthread_sigmask
并忽略所有线程的信号。然后由于SIGPIPE而破坏的函数应该返回-1(我不熟悉openssl,但是当涉及到套接字时,它是write
方式说,套接字在另一边关闭了。)