多线程服务器,信号处理。POSIX

3

我在多线程服务器的信号处理方面遇到了问题。我为每个连接创建一个线程,但我希望有一个选项用于使用SIGINT终止服务器。但是当其中一个线程捕获信号时,情况会变得很棘手。有没有一种方法可以阻止线程获取信号,除了主线程之外?


https://dev59.com/C3HYa4cB1Zd3GeqPN6n9#18314115 - Maxim Egorushkin
2个回答

6

一个线程继承其创建者的信号掩码。

假设创建线程是“主”线程,您可能希望在创建线程之前阻塞所有相关信号,在代码完成后取消阻塞创建线程中的信号。

要修改线程的信号掩码,POSIX定义了 pthread_sigmask()


更新:

当在多线程环境中需要定期执行信号处理时,一种有趣的方法是将所有信号委托给一个单独的线程,该线程除了使用 sigwait() 等待信号到达外不执行任何其他操作。

具体实现步骤如下:

  1. 在"主"线程中,在执行任何其他操作之前,使用 pthread_sigmask() 设置与要处理的信号相对应的信号掩码。
  2. 然后创建用于处理信号的线程。
  3. 再次使用 pthread_sigmask() 在 1. 中阻止所有信号在"主"线程中被处理。
  4. 最后创建所有其他线程。
结果将是,所有在1.下指定的信号都会发送到在2.下创建的线程中。所有其他线程都不会接收到1.下指定的任何信号。

问题在于每次获取连接时我都会创建一个新的线程,因此在创建所有线程之后,我绝对无法解除信号的阻塞。 - darenn
另一个问题是..我的服务器在一个循环中运行 while(running) { msgrcv()... }。当我捕获到信号时,我将running设置为false,但主线程仍然卡在msgrcv上。除了销毁IPC队列并检查EIDRM错误之外,我还有其他方法可以处理吗? - darenn

0

pthread_sigmask() 就是你需要的。只允许在一个特定的线程中处理 SIGINT 信号。


这种方法引入了一个时间竞争,即线程创建和线程调用pthread_sigmask()之间的时间。 - alk
@alk 是的,但这不是一个真正的问题,并且可以通过多种方式轻松解决。 - Netch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接