Spec-Zone.ru › Ruby 2.3

класс Fiber

Родитель:
Объект

Волокна — это примитивы для реализации лёгкой кооперативной конкурентности в Ruby. По сути, они представляют собой способ создания блоков кода, которые могут приостанавливаться и возобновляться, подобно потокам. Основное отличие заключается в том, что они никогда не прерываются, а планирование должно выполняться программистом, а не виртуальной машиной.

В отличие от других моделей бесклеточной лёгкой конкурентности, каждое волокно имеет небольшой стек размером 4 КБ. Это позволяет волокну приостанавливаться из глубоких вложенных вызовов функций внутри блока волокна.

Когда создаётся волокно, оно не запускается автоматически. Вместо этого его необходимо явно запустить, используя метод Fiber#resume. Код, выполняющийся внутри волокна, может передать управление, вызвав Fiber.yield, в результате чего оно передаст управление обратно вызывающей стороне (вызывающей стороне метода Fiber#resume).

При передаче управления или завершении волокно Fiber возвращает значение последнего выполненного выражения.

Например:

fiber = Fiber.new do
  Fiber.yield 1
  2
end

puts fiber.resume
puts fiber.resume
puts fiber.resume

выводит

1
2
FiberError: dead fiber called

Метод Fiber#resume принимает произвольное количество параметров. Если это первый вызов resume, они будут переданы в качестве аргументов блока. В противном случае они будут значением возврата вызова Fiber.yield

Пример:

fiber = Fiber.new do |first|
  second = Fiber.yield first + 2
end

puts fiber.resume 10
puts fiber.resume 14
puts fiber.resume 18

выводит

12
14
FiberError: dead fiber called

Публичные методы класса

current() → fiber Показать исходный код
static VALUE
rb_fiber_s_current(VALUE klass)
{
    return rb_fiber_current();
}

Возвращает текущее волокно. Необходимо require 'fiber' перед использованием этого метода. Если вы не работаете в контексте волокна, этот метод вернёт корневое волокно.

yield(args, ...) → obj Показать исходный код
static VALUE
rb_fiber_s_yield(int argc, VALUE *argv, VALUE klass)
{
    return rb_fiber_yield(argc, argv);
}

Передаёт управление обратно контексту, который возобновил волокно, передавая любые аргументы, которые были ему переданы. Волокно возобновит обработку в этот момент, когда resume будет вызвано снова. Любые аргументы, переданные в следующий resume, будут значением, которое оценивает это выражение Fiber.yield.

Публичные методы экземпляра

alive? → true или false Показать исходный код
VALUE
rb_fiber_alive_p(VALUE fibval)
{
    rb_fiber_t *fib;
    GetFiberPtr(fibval, fib);
    return fib->status != TERMINATED ? Qtrue : Qfalse;
}

Возвращает true, если волокно всё ещё может быть возобновлено (или передано). После завершения выполнения блока волокна этот метод всегда вернёт false. Необходимо require 'fiber' перед использованием этого метода.

resume(args, ...) → obj Показать исходный код
static VALUE
rb_fiber_m_resume(int argc, VALUE *argv, VALUE fib)
{
    return rb_fiber_resume(fib, argc, argv);
}

Возобновляет волокно с точки, в которой был вызван последний Fiber.yield, или начинает его выполнение, если это первый вызов resume. Аргументы, переданные в resume, будут значением выражения Fiber.yield или будут переданы в качестве параметров блока блоку волокна, если это первый resume.

В качестве альтернативы, при вызове resume оно оценивается как аргументы, переданные следующей Fiber.yield инструкции внутри блока волокна, или к значению блока, если оно выполняется до конца без каких-либо Fiber.yield

transfer(args, ...) → obj Показать исходный код
static VALUE
rb_fiber_m_transfer(int argc, VALUE *argv, VALUE fibval)
{
    rb_fiber_t *fib;
    GetFiberPtr(fibval, fib);
    fib->transferred = 1;
    return fiber_switch(fib, argc, argv, 0);
}

Передаёт управление другому волокну, возобновляя его с места остановки или запуская его, если оно не возобновлялось ранее. Вызывающее волокно будет приостановлено, так же как и при вызове Fiber.yield. Необходимо require 'fiber' перед использованием этого метода.

Волокно, которое получает вызов передачи, обрабатывает его так же, как вызов возобновления. Аргументы, переданные в transfer, обрабатываются как те, которые переданы в resume.

Вы не можете возобновить волокно, которое передало управление другому. Это вызовет ошибку двойного возобновления. Необходимо передать управление обратно этому волокну, прежде чем оно сможет передать управление и возобновиться.

Пример:

fiber1 = Fiber.new do
  puts "In Fiber 1"
  Fiber.yield
end

fiber2 = Fiber.new do
  puts "In Fiber 2"
  fiber1.transfer
  puts "Never see this message"
end

fiber3 = Fiber.new do
  puts "In Fiber 3"
end

fiber2.resume
fiber3.resume

выводит

In fiber 2
In fiber 1
In fiber 3

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

Spec-Zone.ru

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