Ruby拡張機能のクロススレッド違反を回避するにはどうすればよいですか?
-
04-10-2019 - |
質問
Rubyと非同期I/Oライブラリの間にインターフェイスを提供するC拡張子を書いています。コードでテストを実行すると、頻繁にエラーが発生します(ただし、これらに限定されません)。
[BUG] cross-thread violation in rb_thread_schedule()
非同期IOは、私のC拡張子が複数のスレッドからRubyにメッセージを配信する必要があることを意味します(メインインタープリタースレッドではありません)。これらのスレッドセーフティ違反をその過程で回避するにはどうすればよいですか?
解決
Ruby 1.8.xの場合、エラーを回避する唯一の方法は明白なものです。メインインタープリタースレッドからRuby/C APIを呼び出すだけです。これはRuby 1.9.xにも当てはまると思いますが、私はそれを使用しておらず、そのネイティブスレッドサポートがどのように変化するかわかりません。複数のネイティブスレッドがAPIを直接呼び出す代わりに、プロデューサー/コンシューマーパターンを使用して、メインインタープリタースレッドのセカンダリネイティブスレッドからコードにリクエストを配信する必要があります。理想的には、他のルビーグリーンスレッドを不必要にブロックしていないが、理想的にはこれを行います。 Rubyの実装を見ると、Ruby Greenスレッドスケジューラは必須です select()
ループ。これは、次の全体的な構造を示唆しています。
- 実際のものを提供するパイプまたは他のIPCメカニズムを作成する
select()
- 可能なファイル記述子。 - ネイティブスレッドをスポーンし、パイプの書き込み端を提供します。
- メインインタープリタースレッドで、呼び出すイベントループを入力します
rb_thread_wait_fd()
パイプの読み取り端に。これにより、Ruby Green Thread Schedulerが他のグリーンスレッドを実行できます。 - セカンダリネイティブスレッドにメインスレッドのリクエストがある場合、イベントループを実行している緑のスレッドを目覚めさせ、パイプに書き込みます。
見る rb_io_sysread()
(の実装 IO#sysread
)Rubyコードベースでおそらく最も単純なIO使用機能は何ですか。
所属していません StackOverflow