CPP线程中的嵌入式Ruby崩溃了

时间:2014-10-21 13:33:48

标签: c++ ruby multithreading embed

我正在创建一个嵌入式Ruby框架,如果我正常/一次运行它。当我尝试在线程循环中运行它时程序崩溃。

有效的例子:

myRubyfile.rb:

def helloworld()
    puts "Hello world"
end

使用main.cpp:

#include <ruby.h>

void runRuby()
{
    ruby_init();
    ruby_init_loadpath();
    rb_require("myRubyfile");
    rb_funcall(rb_mKernel, rb_intern("helloworld"), 0 , NULL);
    ruby_finalize();
}

int main()
{
    runRuby();
    return 0;
}

上述程序正确执行。

但是,我想在多个线程中运行多个Ruby脚本,下面的示例运行一次然后崩溃。

崩溃main.cpp:

#include <ruby.h>
#include <thread>

void runRuby()
{
    ruby_init();
    ruby_init_loadpath();
    rb_require("myRubyfile");
    rb_funcall(rb_mKernel, rb_intern("helloworld"), 0 , NULL);
    ruby_finalize();
}

int main()
{
    for(int i = 0; i < 100; i++) {
        std::thread mythread(runRuby);
        mythread.join();
    }
    return 0;
}

我在Windows中运行它。

为什么会失败?

1 个答案:

答案 0 :(得分:2)

失败是因为Ruby VM不是线程安全的。你需要使用Ruby的Thread类,就像在普通的Ruby中一样。 thread.c具有您需要的大部分功能:

VALUE myThread(VALUE arg)
{
    // ...
}

int main()
{
    ruby_init();

    VALUE threads[100];

    for(int i = 0; i < 100; ++i)
        threads[i] = rb_thread_create(RUBY_METHOD_FUNC(myThread), Qnil);

    for(int i = 0; i < 100; ++i)
        rb_funcall(threads[i], rb_intern("join"), 0);

    return ruby_cleanup(0);
}

由于Ruby的线程不是真正并行的,真正并行加载和运行脚本的唯一方法是在不同的子进程中启动多个VM。