通过信号中断两个阻塞pthread

时间:2012-01-29 20:00:14

标签: c pthreads signals

在我的应用程序中,主线程创建了两个连接的线程;一个通过在循环中调用scanf()来等待用户输入,另一个通过在循环中调用accept()来监听传入的套接字连接。新连接在分离的单独线程中处理。

我希望程序在收到SIGINT信号时正常关闭。这意味着监听线程应该停止接受新连接,等待当前服务连接的线程关闭然后再关闭。等待用户输入的线程也应该结束,从而允许主线程结束。

Scanf()和accept()两个块都可以被信号中断,但是发送到进程的信号只能由一个线程(AFAIK)处理。我的想法是阻止所有线程中的SIGINT信号,除了将等待它的主线程。当它收到一个SIGINT时,它会将SIGUSR1发送到两个线程(一个阻塞在scanf()上,一个阻塞在accept()上),然后加入这些线程。

这是一个很好的解决方案吗?是否有更好的或可能是标准的方法来实现这一目标?

1 个答案:

答案 0 :(得分:5)

这类问题的规范解决方案是Thread Cancellation。在作为取消点的功能中阻塞线程时到达的取消请求将立即起作用;否则,它在下一次线程调用一个取消点的函数时起作用。

使用取消可能唯一令人痛苦的事情是它建立在异常处理模型而不是故障返回上。您需要在大多数时间阻止取消(并且仅在您想要处理取消的操作期间启用它),或者在每个调用帧级别安装取消清理处理程序(基本上是C中的半丑异常处理程序)可能有中间状态/分配/等。清除线程何时被取消。我个人更喜欢第一种方法,通常只需要安装一个取消处理程序。

任何基于中断信号的方法都具有竞争条件。如果在调用阻塞函数之前发送信号,那么当信号处理程序返回时,阻塞函数将被调用并将无限期地阻塞(因为检查“是时候退出了吗?”已成功通过)。 / p>