Embeded Ruby in a CPP thread crashes

I am creating a embedded Ruby framework which works if I run it normally/once. When I try to run it in a threaded loop the program crashes.

Example which works:

myRubyfile.rb:

def helloworld()
    puts "Hello world"
end

Working 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;
}

The above program executes correctly.

However, I want to run several Ruby scripts in multiple threads the below example runs once and then crashes.

Crashing 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;
}

I am running this in Windows.

Why is this failing?

2

It fails because the Ruby VM is not thread safe. You need to use Ruby's Thread class just like in normal Ruby. thread.c has most of the functions you'll need:

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);
}

Since Ruby's threads are not truly parallel the only way to really load and run scripts in parallel is to start multiple VMs in different subprocesses.

 

https://stackoverflow.com/questions/26488029/embeded-ruby-in-a-cpp-thread-crashes

posted @ 2021-08-11 18:38  unicornsir  阅读(49)  评论(0)    收藏  举报