我正在尝试在 C++ 中实现我自己的取消点机制。该代码主要针对 Linux,但我希望它可以在 POSIX 系统中移植。
出于显而易见的原因,每个阻塞系统调用都必须是一个取消点,否则线程可能会永远阻塞并且没有任何东西能够唤醒它。目前我使用信号来实现这一点。当线程接收到表示取消请求的特殊信号时,信号处理程序设置线程本地标志。如果该线程在某些系统调用上被阻塞,它将失败并显示errno == EINTR
. 然后它将有机会检查标志。
但很快我发现上述方法并不完美。如果信号先出现,然后线程进入阻塞系统调用,它也会进入永远阻塞状态。在每次阻塞调用之前检查标志并不能使事情变得足够好。信号可能会在检查之后出现:
if(cancelled)
throw CancellationException();
// <--- The signal comes here. ---> //
blocking_call();
这是我的问题:有没有办法确保当我进入系统调用时,取消标志没有设置?如果不是,设计此类取消点的常见做法是什么?