ORIGINAL:
sqlite3_open_v2函数带有签名:
int sqlite3_open_v2(
const char *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb, /* OUT: SQLite db handle */
int flags, /* Flags */
const char *zVfs /* Name of VFS module to use */
);
第三个参数int flags
支持许多选项,其中一些是不言自明的:
#define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */
/* snip */
#define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */
我的数据库使用情况没有任何问题(但是),但我想知道NOMUTEX与FULLMUTEX和SHAREDCACHE与PRIVATECACHE选项的含义。我发现的sqlite.org页面中的描述对于SQLITE_OPEN_NOMUTEX来说并不是很有帮助。
如果设置了SQLITE_OPEN_NOMUTEX标志,则表示数据库连接 只要单线程,就可以在多线程线程模式下打开 模式尚未在编译时或开始时设置。
如果根据文档已经防止了同时读/写,则互斥锁标志会起什么作用?
此外,缓存中有什么内容,如果我决定分享它,我与谁共享以及它如何影响他们的读/写?
它只在close()上刷新吗?
任何见解都是值得赞赏的,即使是更好描述的链接也会很棒。
答案 0 :(得分:0)
简而言之 解释起来很麻烦,如果你运行单线程,你就不必关心 否则请阅读以下内容:
这是 SQLIte 中最复杂的部分。 如果是第 1 版,我什至会称其为“构思错误”,但由于它是具有一些向后兼容性的渐进式进化,因此我理解开发人员遵循的路径和思维方式。 与阅读官方文档时的感受相反:并非所有组合都有效!!!
此外,虽然模式的决定可以推迟到调用 sqlite3_open_v2(,,,) 之前,但最好一劳永逸地选择。好处是你可以决定多种策略,只要每个策略都在不同的数据库文件中。
说:
SQLITE_OPEN_NOMUTEX 确实编译(或在 sqlite3_open_v2 上激活),SQLite 的使用没有内部互斥锁。 仍然可以安全地使用 SQLite 多线程,但根据我的经验,只有在每个线程中打开单独的连接时才能安全地工作。 请勿尝试使用此模式在 Thread 之间共享连接。
SQLITE_OPEN_FULLMUTEX SQLite 在运行时确实创建了适当的互斥锁来锁定一些原子操作。 我在线程之间共享连接时使用它。 (事实上我总是使用 FULLMUTEX) 如果你想看看在哪里搜索 sqlite3.c for sqlite3_mutex_enter(db->mutex); 并且知道当 NOMUTEX db->mutex == NULL 并且没有锁发生
始终使用 SQLITE_OPEN_FULLMUTEX。 Mutex 处理现在非常快,对性能没有真正的影响。 磁盘/解析在 cpu 中更加繁重,除非您准备对 sqlite3.c 的代码进行逆向工程,否则不清楚 NOMUTEX 的好处是什么
然而 我使用多重连接(每个线程中有一个 open_v2)成功地在多线程中试验了 NOMUTEX,但是使用这个你还需要担心缓存的决定(我使用 SQLITE_OPEN_PRIVATECACHE,不是所有的组合工作,一旦数据库有,特别是缓存系统,也会改变模式一旦已经打开真是自找麻烦) 首次打开前选择MUTEX+CACHE+sync+journal策略并坚持使用。
另见这篇非常好的文章 https://dev.yorhel.nl/doc/sqlaccess