async gem
事例
一見デメリットだがこの特性を活かし、I/Oバウンドな処理においてスループットを上げるのに有用 Fiberを直接使うよりもAsyncを使うと便利
code:ruby
require 'bundler/inline'
require 'csv'
gemfile do
gem 'async'
end
enum = CSV.foreach('input.csv').lazy.map{|row| row'path' }.each_slice(1000) Async do
10000.times do
Async do
loop do
paths = enum.next
# do something
end
end
end
end
上記をThreadで書き直すと以下のようになるが動作しない
code:ruby
require 'bundler/inline'
require 'csv'
gemfile do
gem 'async'
end
enum = CSV.foreach('input.csv').lazy.map{|row| row'path' }.each_slice(1000) threads = []
10000.times do
threads << Thread.new do
paths = enum.next
# do something
end
end
threads.each(&:join)
ただし以下のエラーが起きる
code:txt
s.rb:17:in `next': attempt to resume a resumed fiber (double resume) (FiberError)
複数スレッドから同じEnumeratorにアクセスし、Enumeratorが内部的に利用しているFiberを二重にresumeしているため 同一のFiberを別のスレッドでresumeしないように書くのは難しいため、