C++ 什么时候需要在Ruby C扩展中声明可变值?
我找不到太多的文档说明什么时候应该在Ruby扩展中将C++ 什么时候需要在Ruby C扩展中声明可变值?,c++,c,ruby,garbage-collection,mark-and-sweep,C++,C,Ruby,Garbage Collection,Mark And Sweep,我找不到太多的文档说明什么时候应该在Ruby扩展中将值声明为volatile,以避免对正在使用的对象进行过早的垃圾收集 这是我到目前为止学到的。有人能填空吗 当不需要使用volatile时: C++对象成员中的LI>(因为它们从不在堆栈上) 在不调用Ruby API的C/C++方法中(因为在调用Ruby API之前GC不会打开) 当确实需要使用volatile时 在C/C++方法中,调用任意RubyALLOC或malloc宏/函数(因为这些宏/函数在内存高度碎片化时会触发GC) 在调用任何
值声明为volatile
,以避免对正在使用的对象进行过早的垃圾收集
这是我到目前为止学到的。有人能填空吗
当不需要使用volatile
时:
C++对象成员中的LI>(因为它们从不在堆栈上)
- 在不调用Ruby API的C/C++方法中(因为在调用Ruby API之前GC不会打开)
当确实需要使用volatile
时
- 在C/C++方法中,调用任意Ruby
ALLOC
或malloc
宏/函数(因为这些宏/函数在内存高度碎片化时会触发GC)
- 在调用任何Ruby函数的C/C++方法中(例如,
rb_funcall
,rb_ary\u new
,等等)
避免GC的其他方法
- 标记正在使用的
值
- 在对象创建期间禁用GC,然后重新启用它
- 不要使用Ruby的分配方法(有风险)
一切都对吗?我遗漏了什么细节?除了标记之外,volatile
是唯一的方法吗?将变量标记为volatile
可以防止C/C++编译器基于变量不能“自行”更改值的假设应用某些优化
我认为在C扩展以外的Ruby代码共享或可以更改值时应该使用它,以使编译器意识到这一事实。看看。我认为经验法则是,如果您的变量值可以在运行时的任何时候更改,并且您不知道何时更改,请使用volatile
关键字。这包括中断。例如,您有一个中断回调函数,它计算用户在键盘上按下某个键的次数。您的程序不知道用户何时按下键盘上的按钮,因此必须使用volatile
关键字声明计数器变量
如前所述,它禁用了对变量的一些编译器优化。例如:
int a = 5;
while(a == 5){
//do something
}
编译器将while(a==5)
语句优化为while(true)
,因为它发现变量a在运行时不能更改,并且在每个循环中检查a
的值是没有用的。所以你最终进入了一个无限循环。但是如果添加关键字volatile
:
volatile int a = 5;
while(a == 5){
//do something
}
您只需告诉编译器让变量保持原样。不要对它进行任何优化,一些中断可能会改变它的值。在这一点上,它工作得很好。这是一种误导。在C和C++中,波动性不同。