July 14, 2025

RubyでRactor::Selectorを使う(C APIをRubyから呼び出す)

Rubyで並列処理をするにあたってRuby3から導入されたRactor(日本語のドキュメントが見つからなかったので英語版で…)を使ってみています。まだ試験的導入(Ractor入りのスクリプトを実行すると warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues.とでる)であるため、日々改良が重ねられているようですが、つーすを読んでみると隠し機能があることがわかりました。

Ractor間の通信があったことを補足するRactor::select(*ractors)という関数があるのですが、複数のRactorのメッセージを全て完了するのに、一つずつ減らしながらselectを何度も呼び出すのはオーバーヘッドが大きそうだということに気が付きました。内部的にはRuby 3.3, 3.4ではRactor::Selectorというクラスのインスタンスを生成して、そこにractorsを登録するような仕組みになっていますので、selectを呼ぶためにRactor::Selectorを作ります。もしRactor::Selectorが再利用できれば、オーバーヘッドを少しでも減らせそうです。

しかし残念ながらRactor::Selectorを直接RubyからいじるにはRubyをビルドする時にUSE_RACTOR_SELECTORをdefineする必要がありました。一方よく見てみると、rb_init_ractor_selector()というRactor::SelectorをRubyから見えるようにする関数も公開されていることがわかりました(Ruby 3.4では2567行目付近、3.3も同様の定義です)。

Rubyをビルドしなおすのも少々面倒なので、ここからはサブタイトルになっているRubyのC API(今回でいうとrb_init_ractor_selector)を呼び出すことを考えます。C関数を呼び出せるFFIまたはFiddleを使うことにしました。下記のコードで達成できます。Using Ruby's C API inside Rubyが参考になりました。

最後にもともとのRactor::selectの効率化ですがRactor::Selector#wait, #removeなどが定義されていますので、これを使って実現しました。

00:33 fenrir が投稿 : 固定リンク | | このエントリーを含むはてなブックマーク | トラックバック
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/963
コメント
コメントする









名前、アドレスを登録しますか?
(次回以降コメント入力が楽になります)
  • 匿名でのコメントは受け付けておりません。
  • 名前(ハンドル名可)とメールアドレスは必ず入力してください。
  • メールアドレスを表示されたくないときはURLも必ず記入してください。
  • コメント欄でHTMLタグは使用できません。
  • コメント本文に日本語(全角文字)がある程度多く含まれている必要があります。
  • コメント欄内のURLと思われる文字列は自動的にリンクに変換されます。