【问题标题】:Interrupting two blocking pthreads by signals通过信号中断两个阻塞 pthread
【发布时间】:2012-01-29 20:00:13
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: c pthreads signals


    【解决方案1】:

    此类问题的典型解决方案是Thread Cancellation。当线程在作为取消点的函数中被阻塞时到达的取消请求将立即执行;否则,它会在下次线程调用作为取消点的函数时执行。

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

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

    【讨论】:

    • 谢谢 - 我暗暗希望你能回答这个问题!问题是,一旦一个线程被取消,例如在 accept() 上阻塞时,它后面的任何逻辑都不会运行。我需要线程等待正在处理连接的分离线程,然后在它退出之前释放资源。我怎样才能做到这一点?
    • 啊,pthread_cleanup_push() 是您所说的清理处理程序吗?看起来它可以解决问题。
    • 是的,这就是您使用取消的方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-14
    • 1970-01-01
    • 1970-01-01
    • 2015-09-18
    • 1970-01-01
    相关资源
    最近更新 更多