sqlite3.dylib:对数据库连接的非法多线程访问 [英] sqlite3.dylib: illegal multi-threaded access to database connection
问题描述
我有一个使用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屋!