sqlite3_mutex *sqlite3_mutex_alloc(int); void sqlite3_mutex_free(sqlite3_mutex*); void sqlite3_mutex_enter(sqlite3_mutex*); int sqlite3_mutex_try(sqlite3_mutex*); void sqlite3_mutex_leave(sqlite3_mutex*);
SQLite 核心使用这些例程进行线程同步。尽管它们旨在供 SQLite 内部使用,但链接到 SQLite 的代码可以随意使用这些例程中的任何一个。
SQLite 源代码包含这些互斥锁例程的多个实现。适当的实现会在编译时自动选择。以下实现可在 SQLite 核心
SQLITE_MUTEX_NOOP 实现是一组不执行任何实际锁定的例程,适用于单线程应用程序。SQLITE_MUTEX_PTHREADS 和 SQLITE_MUTEX_W32 实现适用于 Unix 和 Windows。
如果 SQLite 在定义了 SQLITE_MUTEX_APPDEF 预处理器宏(使用“-DSQLITE_MUTEX_APPDEF=1”)的情况下编译,则库中不包含任何互斥锁实现。在这种情况下,应用程序必须使用 SQLITE_CONFIG_MUTEX 选项在调用 sqlite3_initialize() 或任何其他调用 sqlite3_initialize() 的公共 sqlite3_ 函数之前,使用 sqlite3_config() 函数提供自定义互斥锁实现。
sqlite3_mutex_alloc() 例程分配一个新的互斥锁并返回指向它的指针。如果 sqlite3_mutex_alloc() 例程无法分配请求的互斥锁,则返回 NULL。sqlite3_mutex_alloc() 的参数必须是以下整型常量之一
前两个常量(SQLITE_MUTEX_FAST 和 SQLITE_MUTEX_RECURSIVE)导致 sqlite3_mutex_alloc() 创建一个新的互斥锁。当使用 SQLITE_MUTEX_RECURSIVE 时,新互斥锁是递归的,但当使用 SQLITE_MUTEX_FAST 时不一定如此。如果互斥锁实现不想区分 SQLITE_MUTEX_RECURSIVE 和 SQLITE_MUTEX_FAST,则它不需要这样做。SQLite 仅在真正需要的情况下才会请求递归互斥锁。如果主机平台上提供了更快的非递归互斥锁实现,则互斥锁子系统可能会响应 SQLITE_MUTEX_FAST 返回这样的互斥锁。
sqlite3_mutex_alloc() 的其他允许参数(除 SQLITE_MUTEX_FAST 和 SQLITE_MUTEX_RECURSIVE 之外的任何内容)都会返回指向一个静态预先存在的互斥锁的指针。当前版本的 SQLite 使用九个静态互斥锁。SQLite 的未来版本可能会添加其他静态互斥锁。静态互斥锁仅供 SQLite 内部使用。使用 SQLite 互斥锁的应用程序应仅使用 SQLITE_MUTEX_FAST 或 SQLITE_MUTEX_RECURSIVE 返回的动态互斥锁。
请注意,如果使用动态互斥锁参数之一(SQLITE_MUTEX_FAST 或 SQLITE_MUTEX_RECURSIVE),则 sqlite3_mutex_alloc() 在每次调用时都会返回不同的互斥锁。对于静态互斥锁类型,每次具有相同类型编号的调用都会返回相同的互斥锁。
sqlite3_mutex_free() 例程释放先前分配的动态互斥锁。尝试释放静态互斥锁会导致未定义的行为。
sqlite3_mutex_enter() 和 sqlite3_mutex_try() 例程尝试进入互斥锁。如果另一个线程已在互斥锁中,则 sqlite3_mutex_enter() 将阻塞,而 sqlite3_mutex_try() 将返回 SQLITE_BUSY。sqlite3_mutex_try() 接口在成功进入时返回 SQLITE_OK。使用 SQLITE_MUTEX_RECURSIVE 创建的互斥锁可以被同一线程多次进入。在这种情况下,必须退出互斥锁相同次数,然后其他线程才能进入。如果同一线程尝试多次进入任何不是 SQLITE_MUTEX_RECURSIVE 的互斥锁,则行为未定义。
某些系统(例如 Windows 95)不支持 sqlite3_mutex_try() 实现的操作。在这些系统上,sqlite3_mutex_try() 将始终返回 SQLITE_BUSY。在大多数情况下,SQLite 核心仅将 sqlite3_mutex_try() 用作优化,因此这是可以接受的行为。例外情况是设置了 SQLITE_ENABLE_SETLK_TIMEOUT 构建选项的 unix 版本。在这种情况下,需要一个正常工作的 sqlite3_mutex_try()。
sqlite3_mutex_leave() 例程退出先前由同一线程进入的互斥锁。如果互斥锁当前未由调用线程进入或当前未分配,则行为未定义。
如果 sqlite3_mutex_enter()、sqlite3_mutex_try()、sqlite3_mutex_leave() 或 sqlite3_mutex_free() 的参数是 NULL 指针,则所有四个例程的行为都将作为无操作。