【问题标题】:Ruby 1.8.6, SQLite3 thread safetyRuby 1.8.6,SQLite3 线程安全
【发布时间】:2009-11-25 05:36:45
【问题描述】:

sqlite3 Ruby gem 线程安全吗?我找不到任何文件说它是。

在我的实验中,从多个 Ruby 线程访问数据库最终会导致以下错误:

/Library/Ruby/Gems/1.8/gems/sqlite3-ruby-1.2.5/lib/sqlite3/driver/native/driver.rb:84: [BUG] Bus Error

我有什么遗漏吗?如果没有,我可以使用另一个线程安全的包吗?

编辑:在 Mac OS 10.5 上使用 SQLite3.4。

【问题讨论】:

    标签: ruby multithreading sqlite thread-safety


    【解决方案1】:

    这很可能取决于您使用的 sqlite3 库。它可以在打开或关闭线程安全的情况下进行编译。 sqlite3_threadsafe() 函数会告诉你,尽管我怀疑 API 没有在 Ruby 绑定中公开。

    下面的 C 程序会为你测试它

    #include <sqlite3.h>
    #include <stdio.h>
    
    int main()
    {
        printf("Threadsafe: %d\n", sqlite3_threadsafe());
    }
    

    用它编译

    gcc -o test test.c -lsqlite3
    

    如果它打印一个非零数字,那么它应该是线程安全的。

    【讨论】:

    • 谢谢,我没想到直接测试c库。
    • 嗯,有趣的是源代码编译,但没有链接到该函数(尽管 gcc 确实找到了库)。我闻到图书馆安装的恶作剧。
    【解决方案2】:

    经过一番调查,我发现这个问题与sqlite3无关。

    在对数据库执行线程访问的函数中,发生了异常。当Thread.abort_on_exception defaults 为 false 时,异常被屏蔽,但一旦驱动程序.rb 调用 DL 函数,就会表现为总线错误(见上文)

    修复异常(愚蠢的字符串/整数比较)会导致预期的工作行为 - 使用上面的测试确实表明 sqlite 库是使用 -DTHREADSAFE=1 构建的

    注意我仍然有文档推荐的 SQL 查询的互斥锁 (参见 http://www.sqlite.org/cvstrac/wiki?p=MultiThreading ),但这对于 Ruby 1.8 的“绿色”线程可能不是必需的。

    【讨论】:

      猜你喜欢
      • 2010-10-13
      • 1970-01-01
      • 1970-01-01
      • 2016-05-05
      • 2015-10-11
      • 2012-04-08
      • 1970-01-01
      • 2014-05-05
      • 1970-01-01
      相关资源
      最近更新 更多