diary

I like Hatena Star with a text selection.

2020-09-06

def fibo(n)
  n <= 2 ? 1 : fibo(n-1) + fibo(n-2)
end

def each_with_ractor(enum, &block)
  env = Class.new
  env.define_singleton_method :call, &block

  enum.map do |v|
    Ractor.new(v, env) do |v, env|
      env.call(v)
    end
  end.map(&:take)
end

pp each_with_ractor([39]*20) { |n| fibo n }

parallel gem 的なノリで Ractor で each するコードを書いてみた。

env = Class.newしているのは、Proc を Ractor に送り込むため。 単純に block をそのまま送っていないのは、ProcオブジェクトはRactorに送れないため。 ClassクラスのオブジェクトはRactorのチェックをすり抜けるという便利さがあるので、なんとでもできるような気がする。

……と思っていたのだけど、単にRactor.new(v, &block)でもだいたいのケースでは良さそう。 ただし、blockが外側のmutableな変数を参照していると死ぬ。


class C
  a = ''

  define_method :a do
    a
  end
end


10000.times.map do
  Ractor.new do
    C.new.a << 1
  end
end.each(&:take)


p C.new.a.size

RactorでRubyが壊れるコード。結果が10000にならなかったり、double freeになったり、いろんなエラーが出る。

ruby-jp の #concurrency で話していて、Ractor のバグではという話をしている


Ractor.allocate.nandemo_iikara_method_yobidashi

RactorでRubyが壊れるコード。その2

かならずSegmentation faultする