5

私はC拡張機能を作成しており、Rubyと非同期I/Oライブラリ間のインターフェイスを提供しています。コードに対してテストを実行すると、次のようなエラーが頻繁に発生します(ただしこれらに限定されません)。

[BUG] cross-thread violation in rb_thread_schedule()

非同期IOは、C拡張機能が複数のスレッド(メインのインタープリタースレッドではない)からrubyにメッセージを配信する必要があることを意味します。プロセスでこれらのスレッドセーフ違反を回避するにはどうすればよいですか?

4

1 に答える 1

7

ruby 1.8.xの場合、エラーを回避する唯一の方法は明らかな方法です。メインのインタープリタースレッドからRuby /CAPIを呼び出すだけです。これはruby1.9.xにも当てはまると思いますが、私はこれを使用したことがなく、ネイティブスレッドのサポートによって状況がどのように変わるかわかりません。複数のネイティブスレッドでAPIを直接呼び出す代わりに、プロデューサー/コンシューマーパターンを使用して、セカンダリネイティブスレッドからメインインタープリタースレッドのコードにリクエストを配信する必要があります。そして理想的には、他のRubyグリーンスレッドを不必要にブロックせずにこれを実行します。rubyの実装を見ると、rubyグリーンスレッドスケジューラは本質的にselect()ループです。これは、次の全体的な構造を示唆しています。

  • select()実在可能なファイル記述子を提供するパイプまたはその他のIPCメカニズムを作成します。
  • ネイティブスレッドを生成し、パイプの書き込み終了を提供します。
  • rb_thread_wait_fd()メインのインタープリタースレッドで、パイプの読み取り側を呼び出すイベントループに入ります。これにより、ルビーグリーンスレッドスケジューラが他のグリーンスレッドを実行できるようになります。
  • セカンダリネイティブスレッドにメインスレッドのリクエストがある場合、それらはキューに入れられ、パイプに書き込み、イベントループを実行しているグリーンスレッドをウェイクアップします。

ルビーコードベースでおそらく最も単純なクリーンなIO使用関数については、rb_io_sysread()(の実装)を参照してください。IO#sysread

于 2010-09-21T09:14:27.443 に答える