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

与在 C 或大多数其他语言中实现信号处理程序一样,传递给 Signal.trap 的所有代码都必须是可重入的。如果您不熟悉可重入性,请在阅读本文档的其余部分之前,自行查阅 Wikipedia 或其他资料。

最重要的是,“线程安全”并不保证可重入性;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 函数,因此许多 IOFileDirSocket 方法的相应包装器是安全的。

(不完整列表)

...