实现 Signal.trap 回调的注意事项

与在 C 或大多数其他语言中实现信号处理程序一样,传递给 Signal.trap 的所有代码都必须是可重入的。如果您不熟悉可重入性,则在阅读本文档的其余部分之前,需要在 维基百科 或其他地方了解它。

最重要的是,“线程安全”并不能保证可重入性;而像 Mutex#lock 和 Mutex#synchronize 这样通常用于线程安全的方法甚至会阻止可重入性。

Ruby VM 的一个实现细节

Ruby VM 会推迟 Signal.trap 回调的运行,直到其内部数据结构安全为止,但它不知道何时您的代码中的数据结构是安全的。Ruby 通过注册只包含 异步信号安全函数的短 C 函数作为信号处理程序来实现延迟信号处理。这些短 C 函数仅执行足够的告诉 VM 在主 Ruby Thread 中稍后运行通过 Signal.trap 注册的回调。

Signal.trap 代码块中调用的不安全方法

如有疑问,请将下面未列为安全的方法视为不安全的方法。

Signal.trap 代码块中常用的安全操作

Signal.trap 中安全的系统调用包装方法

由于 Ruby 封装了许多 异步信号安全的 C 函数,因此许多 IOFileDir 和 Socket 方法的对应包装是安全的。

(不完整列表)

...