FFI блокирует поток ruby ​​и не может делать вызовы FFI в любом блоке тайм-аута - PullRequest
0 голосов
/ 14 марта 2011

У меня есть файл SO, завернутый с использованием FFI.Мне нужно тайм-аут вызова FFI, но, к сожалению, тайм-аут не происходил ни в одном из популярных методов, как я упоминал в Тайм-аут, системное время ожидания и терминатор не работает для функции на основе FFI .Можно ли указать время ожидания для звонка?

Спасибо за ваши предложения заранее.

Ответы [ 2 ]

2 голосов
/ 31 августа 2012

Я не проверял это, но, судя по коду в library.rb в репозитории ffi, это должна быть более хорошая альтернатива вышеприведенному:

require 'ffi'
module Sleep
  extend FFI::Library

  ffi_lib FFI::Library::LIBC

  attach_function :sleep, [:uint], :void, :blocking => true
end
0 голосов
/ 16 марта 2011

Лучшее решение - использовать среду исполнения 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% надежное решение. Прерывание функции, которая блокируется в нативном коде, обычно работает для функций, которые могут быть прерываемыми (например, режим сна, чтение, запись и т. Д.), Но не для некоторого нативного кода (например, вычисления с интенсивным использованием ЦП, возможно, также для многих других типов).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...