sqlite3.dylib:对数据库连接的非法多线程访问 [英] sqlite3.dylib: illegal multi-threaded access to database connection

查看:771
本文介绍了sqlite3.dylib:对数据库连接的非法多线程访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用sqlite3的iOS应用,并且遇到多线程问题,并通过illegal multi-threaded access to database connection消息使该应用崩溃.当然,这是因为我正在使用多线程.问题是,我的sqlyte3实例配置为使用多线程:

I have an iOS app that uses sqlite3 and I'm facing issues with multi-threading crashing the app with the illegal multi-threaded access to database connection message. Of course, it's because I'm using multi-threading; the problem is, my sqlyte3 instance is configured to use multi-thread:

sqlite3_config(SQLITE_CONFIG_MULTITHREAD);

即使我正在使用多线程(sqlite3 build也使用多线程标志进行编译),当多个线程同时写入或读取数据库时,它也会导致我的应用程序崩溃.

Even though I'm using multi-threading (sqlite3 build was also compiled with the multi-threading flag) it causes my app to crash when multiple threads write or read the database simultaneously.

崩溃报告

Application Specific Information:
BUG IN CLIENT OF sqlite3.dylib: illegal multi-threaded access to database connection

Exception Type:  EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x00000001823ed2fc
Termination Signal: Trace/BPT trap: 5
Termination Reason: Namespace SIGNAL, Code 0x5
Terminating Process: exc handler [0]
Triggered by Thread:  12

Thread 12 Crashed:

0   libsqlite3.dylib                0x00000001823ed2fc sqlite3MutexMisuseAssert + 144 (sqlite3.c:23788)
1   libsqlite3.dylib                0x00000001823ed2ec sqlite3MutexMisuseAssert + 128 (once.h:84)
2   libsqlite3.dylib                0x000000018235248c sqlite3LockAndPrepare + 320 (sqlite3.c:23801)
3   MyCodeCall.m ...........

一段时间以来,我一直在努力解决这个问题,但不幸的是,我在Google上找不到对此的任何引用.

I've been struggling with this issue for a while and I couldn't find any reference to this on google unfortunatelly.

更新

+(sqlite3*) getInstance {
  if (instance == NULL) {
    sqlite3_shutdown();
    sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
    sqlite3_initialize();

    NSLog(@"isThreadSafe %d", sqlite3_threadsafe());

    const char *path = [@"./path/to/db/db.sqlite" cStringUsingEncoding:NSUTF8StringEncoding];

    if (sqlite3_open_v2(path, &database, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, NULL) != SQLITE_OK) {
      NSLog(@"Database opening failed!");
    }
  }

  return instance;
}

推荐答案

事实证明,只要不同时使用同一连接,SQLITE_CONFIG_MULTITHREAD模式在多线程环境中就可以很好地工作.碰巧是我遇到的确切情况.因此,要解决此问题,您可以为每个线程打开一个新连接,也可以在完全互斥模式下使用SQLITE_CONFIG_SERIALIZED,并使用SQLITE_OPEN_FULLMUTEX标志打开连接.

It turns out that SQLITE_CONFIG_MULTITHREAD mode works well on a multi-threading environment as long as you don't use the same connection simultaneously; which happen to be the exact scenario that I had. Therefore, to solve this issue you can either open a new connection for each thread or use SQLITE_CONFIG_SERIALIZED in full mutex mode using SQLITE_OPEN_FULLMUTEX flag to open the connection.

helper方法的最终结果如下:

The helper method ended up like so:

+(sqlite3*) getInstance {
  if (instance == NULL) {
    sqlite3_shutdown();
    sqlite3_config(SQLITE_CONFIG_SERIALIZED);
    sqlite3_initialize();

    NSLog(@"isThreadSafe %d", sqlite3_threadsafe());

    const char *path = [@"./path/to/db/db.sqlite" cStringUsingEncoding:NSUTF8StringEncoding];

    if (sqlite3_open_v2(path, &database, SQLITE_OPEN_READWRITE|SQLITE_OPEN_FULLMUTEX, NULL) != SQLITE_OK) {
      NSLog(@"Database opening failed!");
    }
  }

  return instance;
}

这篇关于sqlite3.dylib:对数据库连接的非法多线程访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆