c - 如何在多线程环境中处理SIGPIPE?

时间:2014-05-27 12:08:36

标签: c linux multithreading signals

我有一个用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作为库(无源代码)

提前致谢。

1 个答案:

答案 0 :(得分:5)

  

有没有办法在线程级别捕获和处理SIGPIPE?我希望相应的线程处理信号,而不是整个进程退出。

是的,有。您需要阻止除一个线程之外的所有线程中的信号(在创建任何线程之前最好这样做)。如果你正在使用pthreads,你可以使用pthread_sigmask,因为这将保证,在调用它之后,每个创建的线程都将继承信号掩码。然后在一个特定的线程中,您需要使用signal注册一个处理程序(不要使用sigaction,它已过时)。

当信号到达你的进程时,它将被阻塞,直到这一个线程将继续它的进程工作(只有那时信号被进程接收,这就是为什么它是未指定的行为 - 它取决于正在运行的线程,但通过阻塞信号在你指定哪一个可以对它作出反应的所有其他线程上。)

其他方式:

如果你想永远不接收这个信号,并且知道哪个套接字被破坏了,你只能使用pthread_sigmask并忽略所有线程的信号。然后由于SIGPIPE而破坏的函数应该返回-1(我不熟悉openssl,但是当涉及到套接字时,它是write方式说,套接字在另一边关闭了。)