2012-01-29 87 views
5

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

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

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

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

回答

5

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

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

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

+0

谢谢 - 我暗自希望你能回答这个问题!问题是,一旦一个线程被取消,例如在accept()上被阻塞时,它之后的任何逻辑都不会运行。我需要线程等待处理连接的分离线程,然后在退出之前释放资源。我怎么能做到这一点? – SlappyTheFish 2012-01-29 21:25:50

+0

啊,是pthread_cleanup_push()你的意思是清理处理程序?看起来它会做的伎俩。 – SlappyTheFish 2012-01-29 21:35:17

+0

是的,这就是你如何使用取消。 – 2012-01-29 23:04:46