Spec-Zone.ru › Ruby 3.2

Особенности реализации обработчиков сигналов Signal.trap

Как и при реализации обработчиков сигналов в C или большинстве других языков, весь код, переданный методу Signal.trap, должен быть реентерабельным. Если вы не знакомы с понятием реентерабельности, перед чтением остальной части документа необходимо ознакомиться с ним на Википедии или в других источниках.

Самое главное, что «безопасность потоков» не гарантирует реентерабельность; а такие методы, как Mutex#lock и Mutex#synchronize, которые обычно используются для обеспечения безопасности потоков, даже препятствуют реентерабельности.

Особенности реализации Ruby VM

Ruby VM откладывает выполнение обработчиков сигналов Signal.trap до момента, когда это безопасно для его внутренних структур данных, но он не знает, когда безопасно работать с структурами данных в вашем коде. Ruby реализует отложенную обработку сигналов, регистрируя короткие C-функции только с функциями, безопасными для обработки сигналов, в качестве обработчиков сигналов. Эти короткие C-функции выполняют только необходимое, чтобы сообщить VM о необходимости выполнить обработчики, зарегистрированные через Signal.trap, позже в основном потоке Ruby Thread.

Небезопасные методы для вызова в блоках Signal.trap

В случае сомнений, считайте любой метод, не указанный ниже как безопасный, небезопасным.

  • Mutex#lock, Mutex#synchronize и любой код, использующий их, явно небезопасен. Это включает Monitor в стандартной библиотеке, который использует Mutex для обеспечения реентерабельности.

  • Dir.chdir с блоком

  • любые операции записи в IO, когда IO#sync имеет значение false; включая IO#write, IO#write_nonblock, IO#puts. Каналы и сокеты по умолчанию имеют ‘IO#sync = true’, поэтому запись в них безопасна, если IO#sync не был отключен.

  • File#flock, так как вызов underlying flock(2) не определен POSIX.

Обычно безопасные операции внутри блоков Signal.trap

  • Присваивание и получение локальных, экземпляра и класса переменных

  • Большинство операций выделения и инициализации объектов, включая Array, Hash, String, Struct, Time.

  • Общие операции с Array, Hash, String, Struct, которые не выполняют блок, обычно безопасны; но будьте осторожны, если итерация происходит где-то еще.

  • Hash#[], Hash#[]= (если Hash.new не был вызван с небезопасным блоком)

  • Thread::Queue#push и Thread::SizedQueue#push (с Ruby 2.1)

  • Создание нового Thread с помощью Thread.new/Thread.start, чтобы обойти невозможность использования Mutex внутри обработчика сигналов

  • Signal.trap безопасно использовать внутри блоков, переданных методу Signal.trap

  • арифметические операции над Integer и Float (‘+’, ‘-’, ‘%’, ‘*’, ‘/’)

    Кроме того, обработчики сигналов не выполняются между двумя последовательными обращениями к локальным переменным, поэтому сокращения, такие как ‘+=’ и ‘-=’, не приведут к гонке данных при использовании с Integer и Float классами в обработчиках сигналов.

Методы-обертки системных вызовов, безопасные внутри Signal.trap

Так как Ruby имеет обертки вокруг многих безопасных для обработки сигналов C-функций, соответствующие обертки для многих IO, File, Dir и Socket методов безопасны.

(Неполный список)

  • Dir.chdir (без аргумента блока)

  • Dir.mkdir

  • Dir.open

  • File#truncate

  • File.link

  • File.open

  • File.readlink

  • File.rename

  • File.stat

  • File.symlink

  • File.truncate

  • File.unlink

  • File.utime

  • IO#close

  • IO#dup

  • IO#fsync

  • IO#read

  • IO#read_nonblock

  • IO#stat

  • IO#sysread

  • IO#syswrite

  • IO.select

  • IO.pipe

  • Process.clock_gettime

  • Process.exit!

  • Process.fork

  • Process.kill

  • Process.pid

  • Process.ppid

  • Process.waitpid

…

Ruby Core © 1993–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API