实现 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 方法的相应包装器是安全的。

(不完整列表)