我正在实现一个简单的窗口库作为Ruby C扩展。 Windows有handle_events!
方法进入其本机事件循环。
问题是我想要每个窗口一个事件循环和方法块。我想立即返回的方法让循环在一个单独的线程中运行。实现这一目标的最佳方法是什么?
我尝试使用rb_thread_call_without_gvl
来调用事件循环函数,然后使用rb_thread_call_with_gvl
来调用窗口的回调,即Proc
s。完整的源代码可以找到here。
它仍然有效,但不是我想要的:该方法仍然阻止。这是否可以使用Ruby的线程模型?
答案 0 :(得分:0)
我有同样的问题需要解决。由于rb_thread_call_with_gvl()在1.9.2中被标记为实验并且它不是导出的符号,我采用了不同的方法:
我调用了阻塞handle_event!函数来自一个单独的线程。我使用了第二个ruby线程,它阻塞了一个消息队列。阻塞消息队列时,gvl与rb_thread_blocking_region()一起发布。
如果现在线程调用handle_event!由于事件而被解锁,它会在队列元素中一起提取Proc的上行所需的所有信息,并将该元素推送到队列中。 ruby线程接收到从rb_thread_blocking_region()返回的元素,从而重新获取gvl并使用接收到的元素中的信息调用Proc。
亲切的问候 托
答案 1 :(得分:0)
据我了解,仍然需要在同一个线程上使用rb_thread_call_with_gvl()
。即:它是关于释放和获取全局锁定,而不是真正改变线程。例如,长时间运行的gzip函数可以在没有锁的情况下运行,以便其他ruby线程可以并行运行。
如果你想让你的Procs在另一个线程上回调,你不应该为那些Procs创建一个ruby线程吗?然后在该线程上,使用rb_thread_call_without_gvl()
调出不保持GVL(允许其他ruby线程运行),然后当您在辅助窗口线程上有事件时,调用rb_thread_call_with_gvl()
来获取锁定那么你应该在同一个线程上调用Proc。
这就是我理解它的方式......(没有很长时间地完成C扩展。)