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

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

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

Ruby VM 的一个实现细节

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

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

如有疑问,请将下面未列为安全的任何内容都视为不安全。

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

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

由于 Ruby 具有许多 async-signal-safe C 函数 的包装器,因此许多 IOFileDirSocket 方法的相应包装器是安全的。

(不完整列表)

...