【发布时间】:2018-08-18 07:47:26
【问题描述】:
我有一个使用 sqlite3 的 iOS 应用程序,我遇到了多线程问题,该应用程序使用 illegal multi-threaded access to database connection 消息使应用程序崩溃。当然是因为我用的是多线程;问题是,我的 sqlite3 实例配置为使用多线程:
sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
即使我使用多线程(sqlite3 构建也使用多线程标志编译),当多个线程同时写入或读取数据库时,它会导致我的应用程序崩溃。
崩溃报告
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 ...........
我一直在为这个问题苦苦挣扎,不幸的是,我在谷歌上找不到任何参考。
更新
+(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_OPEN_NOMUTEX标志作为sqlite3_open_v2调用的一部分打开了数据库? -
@rmaddy 不,我正在使用 sqlite3 api
sqlite3_open。 -
你真的应该使用
sqlite3_open_v2。始终使用较新的 API。 -
@rmaddy 我已更改为
sqlite3_open_v2,但仍然没有区别,相同的异常导致应用程序崩溃。我已经用 db helper 方法更新了问题。 -
所以将
| SQLITE_OPEN_NOMUTEX添加到其他打开的标志没有帮助?