私は引数をrb_thread_call_without_gvl
に渡すのに苦労しています。これは私が使用している簡単なコードです。Rubyグローバルインタープリタロック(GIL) - rb_thread_call_without_gvl
#include <stdio.h>
#include <ruby.h>
#include <ruby/thread.h>
VALUE summa(VALUE self, VALUE x)
{
double result;
result = NUM2DBL(x) + NUM2DBL(x);
printf("The sum in C is %f\n", result);
return DBL2NUM(result);
}
VALUE no_gvl(VALUE self)
{
double arg = 3.0;
double *ptr = &arg;
rb_thread_call_without_gvl(summa, ptr, NULL, NULL);
return Qnil;
}
void Init_csum()
{
VALUE myModule = rb_define_module("MyModule");
VALUE myClass = rb_define_class_under(myModule, "MyClass", rb_cObject);
rb_define_method(myClass, "summa", summa, 1);
rb_define_method(myClass, "no_gvl", no_gvl, 0);
}
私は、スクリプトclient.rb
でルビーから拡張子を呼び出そう:私はCでの初心者ですが、私は必要
require 'mkmf'
extension_name = 'csum'
create_makefile(extension_name)
:
require './csum'
obj = MyModule::MyClass.new # MyClass is defined in C
puts "The sum in R is " + obj.summa(7.0).to_s
puts obj.no_gvl
そして最後に、私のextconf.rb
1つのスレッドの制限なしにライブラリを使用できる拡張機能を作成します。私のother questionを参照してください。
私は、私はそれが言うことを理解しますが、私はそれを修正する方法を見ることができない
warning: incompatible pointer types passing 'VALUE (VALUE, VALUE)' to parameter of type 'void *(*)(void *)'
を言って警告を受ける拡張をmake
。私はそれを無視する必要がありますか? またclient.rb
を実行すると、obj.no_gvl
を呼び出すとセグメント化エラーが発生します。
私はMac OSX 10.10.5を使用しており、Ruby 2.0.0-p247からrbenv
まで使用しています。
非常に明確な感謝。 Re:Rubyのバージョン。このバージョンは、プラグインを作成しているソフトウェア(SketchUp)に組み込まれているため、このバージョンを使用する必要があります。また、私は[this](http://stackoverflow.com/questions/36245878/releasing-the-global-vm-lock-in-ac-extension-without-using-another-function)の問題をよく理解していると思います。質問。私は今、結果をRubyに返そうとしています。私の理解が正しいなら、私は 'void *'を返し、 'double_no_gvl'の' double'にキャストする必要があります。 – Rojj
@Rojjはい、割り当てには注意してください。ローカル変数へのポインタを呼び出し関数に返すべきではありません。ポインタがスタックのどこかを指し示す呼び出し関数のように(次回は関数を呼び出すときに上書きされるでしょう)。あなたがそれを解凍してもそれは働くかもしれませんが、危険です。代わりに、いくつかの記憶領域を 'malloc'する必要があります(呼び出し関数内で' free')するか、必要な引数を含む構造体へのポインタを渡し、結果を返すのではなく設定します結果)。 – matt