Spec-Zone.ru › Ruby 2.5

класс Fiber

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

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

В отличие от других моделей бесклеточной лёгкой конкурентности, каждое волокно имеет свой стек. Это позволяет волокну приостанавливаться из глубоко вложенных вызовов функций внутри блока волокна. Для настройки размера стека волокна(ов) обратитесь к справочной странице ruby(1).

При создании волокна оно не будет выполняться автоматически. Вместо этого его необходимо явно запустить, используя метод 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 or false Показать исходный код
VALUE
rb_fiber_alive_p(VALUE fibval)
{
    const rb_fiber_t *fib;
    GetFiberPtr(fibval, fib);
    return FIBER_TERMINATED_P(fib) ? Qfalse : Qtrue;
}

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

inspect()
Псевдоним для: to_s
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

to_s → string Показать исходный код
static VALUE
fiber_to_s(VALUE fibval)
{
    const rb_fiber_t *fib;
    const rb_proc_t *proc;
    char status_info[0x10];

    GetFiberPtr(fibval, fib);
    snprintf(status_info, 0x10, " (%s)", fiber_status_name(fib->status));
    if (!rb_obj_is_proc(fib->first_proc)) {
        VALUE str = rb_any_to_s(fibval);
        strlcat(status_info, ">", sizeof(status_info));
        rb_str_set_len(str, RSTRING_LEN(str)-1);
        rb_str_cat_cstr(str, status_info);
        return str;
    }
    GetProcPtr(fib->first_proc, proc);
    return rb_block_to_s(fibval, &proc->block, status_info);
}

Возвращает строку информации о волокне.

Также алиас для: inspect
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. Аргументы, переданные в 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