c - 如何避免 Ruby 扩展中的跨线程冲突?

标签 c ruby multithreading ruby-c-extension

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

[BUG] cross-thread violation in rb_thread_schedule()

异步 ​​IO 意味着我的 C 扩展需要从多个线程(不是主解释器线程)向 ruby​​ 传递消息。我如何在此过程中避免这些线程安全冲突?

最佳答案

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

  • 创建管道或其他 IPC 机制,以提供真正的 select() 可用文件描述符。
  • 生成 native 线程并为它们提供管道的写入端。
  • 在主解释器线程中,进入一个事件循环,在管道的读取端调用 rb_thread_wait_fd()。这将允许 ruby 绿色线程调度程序运行其他绿色线程。
  • 当您的辅助 native 线程有对主线程的请求时,它们会将它们排队并写入管道,唤醒运行您的事件循环的绿色线程。

查看 rb_io_sysread()(IO#sysread 的实现)可能是 ruby​​ 代码库中最简单的干净 IO 使用函数。

关于c - 如何避免 Ruby 扩展中的跨线程冲突?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3752006/

相关文章:

c - 处理双重间接时避免不兼容的指针警告

c - 当向hashmap中的链表添加第一个节点时,为什么必须将新节点直接分配给索引指针?

ruby-on-rails - ruby 网 :SSH Control Master?

锁定特定对象的 Java 线程

java - 具有嵌套 ArrayList 的对象的线程安全 HashMap

C: signal() 是进程级的吗?

c - MQTT 回调处理

c++ - CGI 脚本还是编程?工具?

ruby - 如何优化 GraphViz 输出宽度?

ruby - 检查子数组中的所有项目是否相同 Ruby