私は、Ruby スレッドではなく、Ruby スレッド内から C++ コードでいくつかのより大きな Ruby データ構造を構築しなければならない状況にいます。
スタック上に作成された Ruby オブジェクトは、Ruby GC によって収集されないように特別に処理する必要がありますか? オブジェクトが Ruby で作成されているか、Ruby 以外のスレッドで作成されている場合、違いはありますか?
例:
VALUE h = rb_hash_new();
VALUE k = rb_str_new2( "foo" );
VALUE v = rb_str_new2( "foo" );
rb_hash_aset( h, k, v );
すべての関数呼び出しがメモリを割り当てて、ガベージ コレクターを呼び出すことができると思います。グローバル変数を介して到達可能になるまで、h、k、および v が収集されないように特別な注意を払う必要がありますか? 多分このように:
VALUE h = Qnil;
VALUE k = Qnil;
VALUE v = Qnil;
rb_gc_register_address( &h );
rb_gc_register_address( &k );
rb_gc_register_address( &v );
VALUE k = rb_str_new2( "foo" );
VALUE v = rb_str_new2( "foo" );
rb_hash_aset( h, k, v );
rb_gc_unregister_address( &k );
rb_gc_unregister_address( &v );
2 番目のバージョンははるかに複雑なので、GC がすべてのスレッドをスキャンして参照の可能性を探すという保証がある場合は、これを避けたいと思います。
編集:おそらくrb_gcのような関数を使用すべきではないことに気づきました... gvlを保持しない非ルビースレッドから。したがって、GC が Ruby スタックからの参照をマークするという保証があれば十分です。
TIAトルステン