1、SQLite多线程
SQLite支持三种不同的线程模式:
①单线程(Single-thread)
该模式下,所有的互斥锁被禁用;SQLite在多线程中使用是不安全的。
当SQLite编译时加了SQLITE_THREADSAFE=0参数,或者在初始化SQLite前调用sqlite3_config(SQLITE_CONFIG_SINGLETHREAD)时启用该模式。
②多线程(Multi-thread)
这种模式下,SQLite在多线程中同时使用单个数据库连接是不安全的,否则就是安全的。(不能在多个线程中并发使用同一个数据库连接)。
③串行(Serialized)
在串行模式下,SQLite在多线程中使用是安全的。
线程模式可以在编译时(通过源码编译sqlite库时)、启动时(使用sqlite的应用程序初始化时)或者运行时(创建数据库连接时)来指定。一般而言,运行时指定的模式将覆盖启动时的指定模式,启动时指定的模式将覆盖编译时指定的模式。但是,单线程模式一旦被指定,将无法被覆盖。
默认的线程模式是串行模式。
编译时选择线程模式
可以通过定义SQLITE_THREADSAFE宏来指定线程模式:
SQLITE_THREADSAFE=1指定使用串行模式;
SQLITE_THREADSAFE=0使用单线程模式;
SQLITE_THREADSAFE=2使用多线程模式。
如果没有指定,默认为串行模式。
官方链接:Using SQLite In Multi-Threaded Applications
2、iOS平台的SQLite
在iOS平台上,默认使用的是第2种线程模式编译的(Multi-thread),也就是只有一个线程能够打开数据库操作,其他线程要操作数据库必须等数据库关闭后才能打开操作。多线程时:每个线程独立打开数据库,操作数据库,操作完后关闭数据库。打开和关闭都比较费时间,而且要手动控制打开关闭锁,在每个线程操作不频繁时可用该方法。
如果多个线程频繁操作数据库,使用以上方法很容易造成系统崩溃,解决方案:
①开启第3种串行模式,使用一个类(单例方式)操作数据库。
②使用串行队列操作数据库。
2.1 开启第3种串行模式,使用一个类(单例方式)操作数据库。
– (BOOL)open {
if (_db) {
return YES;
}
int err = sqlite3_config(SQLITE_CONFIG_SERIALIZED);
if(err != SQLITE_OK) {
NSLog(@”error configing!: %d”, err);
return NO;
}
err = sqlite3_open([self sqlitePath], (sqlite3**)&_db );
if(err != SQLITE_OK) {
NSLog(@”error opening!: %d”, err);
return NO;
}
if (_maxBusyRetryTimeInterval > 0.0) {
// set the handler
[self setMaxBusyRetryTimeInterval:_maxBusyRetryTimeInterval];
}
return YES;
}
2.2 使用串行操作队列操作数据库。
1、创建操作列队
– (id)initWithPath:(NSString *)path
{
self = [super init];
_path = path;
_databaseQueue = [[NSOperationQueue alloc] init];
[_databaseQueue setMaxConcurrentOperationCount:1];
return self;
}
– (void)queueDatabaseOperation:(StorageOperation *)request
{
[_databaseQueue addOperation:request];
}
原文:https://blog.csdn.net/xuhen/article/details/78967846