【发布时间】:2014-09-16 21:46:10
【问题描述】:
我在使用 C 扩展中的线程来异步运行 ruby 代码时遇到问题。
我有以下 C 代码:
struct DATA {
VALUE callback;
pthread_t watchThread;
void *ptr;
};
void *executer(void *ptr) {
struct DATA *data = (struct DATA *) ptr;
char oldVal[20] = "1";
char newVal[20] = "1";
pthread_cleanup_push(&threadGarbageCollector, data);
while(1) {
if(triggerReceived) {
rb_funcall(data->callback, rb_intern("call"), 0);
}
}
pthread_cleanup_pop(1);
return NULL;
}
VALUE spawn_thread(VALUE self) {
VALUE block;
struct DATA *data;
Data_Get_Struct(self, struct DATA, data);
block = rb_block_proc();
data->callback = block;
pthread_create(&data->watchThread, NULL, &executer, data);
return self;
}
我使用它是因为我想提供 ruby-code 作为回调,一旦线程接收到信号就会执行。
一般来说,如果回调是这样的 ruby-code:
1 + 1
但是,如果回调 ruby 代码如下所示:
puts "test"
一旦回调被执行,主 ruby 进程将停止响应。 线程仍在运行并且能够对信号做出反应并每次进行“测试”,线程接收到消息。
谁能告诉我,如何解决这个问题?
非常感谢
【问题讨论】:
-
我认为它不受支持,MRI 有 GIL 是有原因的:我猜它至少会干扰 GC。您可以尝试向 Ruby 邮件列表询问,在我看来这是一个更合适的地方
-
嘿,据我了解 GIL,每次只有一个线程能够进行 IO。这对我来说完全没问题。但不知何故,在我的线程中的 IO 完成后,主程序无法继续工作。没关系,如果主进程暂时停止工作,另一个线程正在做 IO,但之后,它应该继续工作。所以也许我必须在线程中执行 ruby 代码后释放 GIL?
-
您尝试做的事情很有趣,但这与我对 Ruby 内部原理的理解相去甚远,而且我认为您不会在 SO 上找到如此专精于 Ruby 的人来回答您;我建议尝试Ruby mailing list 如果你这样做,请告诉我,我想关注讨论;)
标签: c ruby multithreading ruby-c-extension