CPP线程中嵌入的Ruby崩溃

Embeded Ruby in a CPP thread crashes

本文关键字:Ruby 崩溃 线程 CPP      更新时间:2023-10-16

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

工作示例:

myRubyfile.rb:

def helloworld()
    puts "Hello world"
end

工作主.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中运行此程序。

为什么会失败?

它失败是因为Ruby虚拟机不是线程安全的。您需要像使用普通Ruby一样使用Ruby的Thread类。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。