Я знаю, что волокна являются кооперативными нитями. Волокно контролирует контекст выполнения, тогда как превентивный поток не работает. Волокно может давать контроль, что означает, что волокно может начинаться и останавливаться в четко определенных местах.управляющий поток в программе рубинового волокна
По-видимому, причина, по которой волокна используются в рубине, заключается в очистке вложенных блоков, вызванных шаблоном реактора.
Но я с трудом пытаюсь понять поток управления приведенного ниже сценария, который использует волокно.
def http_get(url)
f = Fiber.current
http = EventMachine::HttpRequest.new(url).get
# resume fiber once http call is done
http.callback { f.resume(http) }
http.errback { f.resume(http) }
return Fiber.yield
end
EventMachine.run do
Fiber.new{
page = http_get('http://www.google.com/')
puts "Fetched page: #{page.response_header.status}"
if page
page = http_get('http://www.google.com/search?q=eventmachine')
puts "Fetched page 2: #{page.response_header.status}"
end
}.resume
end
Я так понимаю:
1) ЭМ начинает свой цикл событий
2) Волокно создается, а затем резюме называется. Выполняется ли блок кода, переданный в новый, сразу же, или выполняется его после возобновления?
3) http_get называется в первый раз. Он выполняет асинхронное событие (используя select, poll или epoll для linux). Мы настроили обработчик события (в методе обратного вызова) асинхронного события. Затем Fiber добровольно дает управление потоку EventMachine включен (основной поток). Однако, как только будет вызван обратный вызов, он вернет управление с помощью f.resume (http). Но в этом упрощенном примере я должен поставить свой код обратного вызова после f.resume (http)? Потому что прямо сейчас кажется, что f.resume (http) просто возвращает управление волокну и ничего не делает.
Я думаю, что после выхода управление переходит к EventMachine, где он входит в цикл событий. Таким образом, второй http_get еще не вызывается. Теперь, когда обратный вызов вызывается, тогда управление возвращается в Fiber (мы используем только один Fiber.new, поэтому я предполагаю, что во всем этом есть только один экземпляр Fiber). Но когда вызывается второй http_get?
Примечание к себе: при создании волокна оно не запускается автоматически. Скорее, это должно быть явно предложено работать с использованием метода возобновления Fiber #. – Donato