我的情况是,我必须在 C++ 代码中从 ruby 线程而不是 ruby 线程中构建一些更大的 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 );
第二个版本要复杂得多,所以我想避免它,如果有任何保证 GC 扫描所有线程以查找可能的引用。
编辑:我刚刚意识到,我可能不应该使用 rb_gc 之类的函数...来自不包含 gvl 的非 ruby 线程。因此,保证 GC 将标记来自 ruby 堆栈的引用就足够了。
TIA 托尔斯滕