calling IO Operations from thread in ruby c extension will cause ruby to hang

情到浓时终转凉″ 提交于 2019-12-07 23:38:26

From the Ruby C API docs:

As of Ruby 1.9, Ruby supports native 1:1 threading with one kernel thread per Ruby Thread object. Currently, there is a GVL (Global VM Lock) which prevents simultaneous execution of Ruby code which may be released by the rb_thread_call_without_gvl and rb_thread_call_without_gvl2 functions. These functions are tricky-to-use and documented in thread.c; do not use them before reading comments in thread.c.

TLDR; the Ruby VM is not currently (at the time of writing) thread safe. Check out this nice write-up on Ruby Threading for a better overall understanding of how to work within these confines.

You can use Ruby's native_thread_create(rb_thread_t *th) which will use pthread_create behind the scenes. There are some drawbacks that you can read about in the documentation above the method definition. You can then run your callback with Ruby's rb_thread_call_with_gvl method. Also, I haven't done it here, but it might be a good idea to create a wrapper method so you can use rb_protect to handle exceptions your callback may raise (otherwise they will be swallowed by the VM).

VALUE execute_callback(VALUE callback)
{
    return rb_funcall(callback, rb_intern("call"), 0);
}

// execute your callback when the thread receives signal
rb_thread_call_with_gvl(execute_callback, data->callback);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!