我正在编写C扩展名,并在Ruby和异步I/O库之间提供接口。通过我的代码运行测试时,我经常会遇到错误(但不限于):

[BUG] cross-thread violation in rb_thread_schedule()

异步IO意味着我的C扩展名需要从多个线程(而不是主解释器线程)向Ruby传递消息。在此过程中,如何避免这些违规行为?

有帮助吗?

解决方案

对于Ruby 1.8.x,避免错误的唯一方法是显而易见的 - 仅调用主解释器线程中的Ruby/C API。我相信这也适用于Ruby 1.9.x,但我没有使用它,也不知道其本机线程支持如何改变事物。您需要使用生产者/消费者模式将多个本机线程直接调用API,将请求从次级本机线程传递到主解释器线程中的代码。理想情况下是这样做的,而不会不必要地阻止其他红宝石绿色线。如果您查看Ruby的实现,Ruby Green Thread Scheduler实际上是一个 select() 环形。这表明以下整体结构:

  • 创建管道或其他IPC机制,该机制提供真实 select()-able文件描述符。
  • 产卵本地线并为它们提供管道的写入端。
  • 在主解释器线程中,输入呼叫的事件循环 rb_thread_wait_fd() 在管道的读取端。这将允许Ruby Green线程调度程序运行其他绿色线程。
  • 当您的次级本地线程要求主线程请求时,它们会排队并写入管道,唤醒运行事件循环的绿色线程。

rb_io_sysread() (实施 IO#sysread)可能是Ruby代码库中最简单的干净IO使用功能。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top