私はファイバーが協調スレッドであることを知っています。ファイバーは実行コンテキストを制御しますが、プリエンプティブ・スレッドは実行コンテキストを制御しません。ファイバが制御を行うことができます。つまり、ファイバは明確に定義された場所で開始および停止できます。rubyファイバープログラムの制御フロー
明らかに、事象が発生したルビーにおいて繊維が使用される理由は、反応器パターンによって引き起こされるネストされたブロックを清掃することである。
しかし、ファイバを使用する以下のスクリプトの制御フローを把握しようとするのは難しいです。
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)EMは、繊維が作成され、その後、履歴書が呼ばれた)
2のイベントループを開始します。 newに渡されたコードブロックがすぐに実行されるか、またはresumeが呼び出された後に実行されますか?
3)http_getが最初に呼び出されます。これは非同期イベントを行います(Linuxではselect、poll、またはepollを使用します)。非同期イベントの(コールバックメソッド内の)イベントハンドラを設定します。次に、ファイバーは自発的にEventMachineがオンになっているスレッド(メインスレッド)に制御権を与えます。ただし、コールバックが呼び出されるとすぐに、f.resume(http)を使用して制御を取り戻します。しかし、この簡単な例では、f.resume(http)の後に私自身のコールバックコードを置くことになっていますか?今のところ、f.resume(http)のように見えるのは、ファイバーに制御権を戻すだけで、何もしません。
降伏後に何が起こるかは、コントロールがイベントループに入るEventMachineに行きます。したがって、2番目のhttp_getはまだ呼び出されていません。いったんコールバックが呼び出されると、コントロールはファイバーに戻されます(私たちは1つのファイバーを使用します。ニューです。だから、この中に1つのファイバー・インスタンスしかないと仮定します)。しかし、いつ2番目のhttp_getが呼び出されますか?
自分自身への注意:ファイバーを作成すると、ファイバーは自動的には実行されません。むしろ、Fiber#resumeメソッドを使用して明示的に実行する必要があります。 – Donato