我不明白为什么在Ruby中发布或获取GVL时还需要另一个级别的间接定向。
rb_thread_call_without_gvl()
和rb_thread_call_with_gvl()
都需要一个只接受一个参数的函数,而这种情况并不总是如此。我不想仅仅为了释放GVL而将我的论点包装在一个结构中。它使代码的可读性变得复杂,并要求从指针转换为无效指针。
在查看了Ruby的线程代码之后,我找到了与Python的GVL_UNLOCK_BEGIN
/GVL_UNLOCK_END
宏相匹配的Py_END_ALLOW_THREADS
,但是我无法找到关于它们的文档,以及它们何时可以安全使用。
BLOCKING_REGION
宏也在rb_thread_call_without_gvl()
中使用,但我不确定在不调用rb_thread_call_without_gvl()
本身的情况下将其作为独立使用是否安全。
在不需要调用其他函数的情况下,在执行流中间安全地发布的正确方法是什么?
发布于 2016-04-02 21:11:44
在Ruby2.x中,只有Ruby。GVL_UNLOCK_BEGIN
和GVL_UNLOCK_END
是仅在thread.c
中定义的实现细节,因此对于thread.c
扩展来说是不可用的。因此,您的问题的直接答案是“在不调用另一个函数的情况下无法正确和安全地释放GVL”。
以前有一个“基于区域的”API,rb_thread_blocking_region_begin
/rb_thread_blocking_region_end
,但是这个API在Ruby1.9.3中被废弃了,在Ruby2.2中被删除了(关于CAPI的废弃时间表,请参阅definitions )。
因此,不幸的是,您只能使用rb_thread_call_without_gvl
。
尽管如此,你还是可以做一些事情来减轻疼痛。在标准C中,大多数指针和void *
之间的转换是隐式的,因此不必添加强制转换。此外,使用指定的初始化器语法可以简化参数结构的创建。
因此,您可以编写
struct my_func_args {
int arg1;
char *arg2;
};
void *func_no_gvl(void *data) {
struct my_func_args *args = data;
/* do stuff with args->arg... */
return NULL;
}
VALUE my_ruby_function(...) {
...
struct my_func_args args = {
// designated initializer syntax (C99) for cleaner code
.arg1 = ...,
.arg2 = ...,
};
// call without an unblock function
void *res = rb_thread_call_without_gvl(func_no_gvl, &args, NULL, NULL);
...
}
虽然这并不能解决你最初的问题,但它至少能让你更容易接受(我希望)。
发布于 2016-04-02 20:19:08
在执行流中间安全地释放GVL而不必调用另一个函数的正确方法是什么?
您必须使用所提供的API,否则您使用的任何方法最终都会中断。GVL的API是在thread.h
中定义的。
void *rb_thread_call_with_gvl(void *(*func)(void *), void *data1);
void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
rb_unblock_function_t *ubf, void *data2);
void *rb_thread_call_without_gvl2(void *(*func)(void *), void *data1,
rb_unblock_function_t *ubf, void *data2);
您在标题中发现的是API的使用者和API的作者之间的协议,把它看作是一种契约。在.c
中发现的任何东西,特别是静态方法和宏,都不适合在文件之外使用,除非在头文件中找到。static
关键字阻止了这种情况的发生,这是它存在的原因之一,也是C中最重要的用途之一。您可以在thread.c
中穿插,但是使用它的任何东西都违反了API的约定,即它不安全,而且永远不会安全。
,我不是建议您做这个,但是您要做的唯一方法是将它们的部分实现复制到您自己的代码中,这不会通过代码评审。您需要复制的代码数量可能会使您为安全使用API而需要做的任何事情都相形见绌。
https://stackoverflow.com/questions/36245878
复制相似问题