Лучшее решение - использовать среду исполнения ruby, не имеющую GIL (глобальную блокировку интерпретатора), такую как JRuby, - она должна правильно обрабатывать прерванные заблокированные вызовы FFI.
В других средах исполнения ruby, чтобы сделать собственный вызов прерываемым, необходимо пометить функцию как «блокирующую» функцию - FFI разблокирует GIL вокруг вызовов этой функции, а также настроит ее на прерывание.
, например
require 'ffi'
module Sleep
extend FFI::Library
ffi_lib FFI::Library::LIBC
# Tell FFI that this function may block
@blocking = true
attach_function :sleep, [:uint], :void
end
@ блокировка не является липкой - ее нужно устанавливать перед каждым вызовом attach_function, который вы хотите пометить как блокирующий.
И это не 100% надежное решение. Прерывание функции, которая блокируется в нативном коде, обычно работает для функций, которые могут быть прерываемыми (например, режим сна, чтение, запись и т. Д.), Но не для некоторого нативного кода (например, вычисления с интенсивным использованием ЦП, возможно, также для многих других типов).