首页 > 解决方案 > 在条件和阻塞调用之间收到 C/C++ SIGINT

问题描述

线程 A 在循环中执行阻塞调用,直到线程 B 向它发出信号以继续其余的执行。

我尝试了信号处理程序的经典方法,它将更改条件变量,因此我可以在下一次调用开始之前测试条件。

现在问题出现在这种情况下,当信号在条件检查之后但在阻塞调用之前到达时。

问题的简短伪代码示例:

while(!isInterrupted){
  raise(SIGINT)
  block()
}  

假设我无法访问或更改阻塞代码的实现,并且阻塞调用不提供内部超时功能,信号处理程序可以将其设置为最小值,那么 C 和 C++ 处理这个的正确方法是什么?

信号被用作阻塞调用,只能通过接收 SIGINT 来唤醒。

预先感谢您的帮助。

标签: c++csignals

解决方案


如果您可以像我使用https://github.com/pskocik/musl那样修改 libc 的调用程序集,那么您可以通过让信号处理程序调用来消除这种检查时间到使用时间的问题特殊函数(在修改后的 libc 中提供)如果在您的代码在检查后位于函数调用包装器中但尚未处于内核模式时接收到信号,则会中断系统调用(在内核模式下,阻塞调用自然会被中断)信号传递自然)。

如果无法访问您的 libc(/您纯粹在 POSIX 之上构建),我相信您能做的最好的事情就是基于协议的解决方案:

  • 建立一种机制,信号接收者通过该机制确认信号接收
  • 重复发送信号的代码(最好是在休眠的情况下),直到收到确认

不过,这可能不是最容易设置的(本质上,您会在一定程度上与 POSIX 作斗争)。如果您负担得起,在新线程中执行阻塞操作应该更简单,并且pthread_cancel与 不同pthread_kill,应该能够在目标中可靠地引发响应(在这种情况下,完全线程取消),pthread_kill

使用单独线程的缺点是它会占用更多资源。


推荐阅读