Mutexes
互斥
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_PTHREADS
- SQLITE_MUTEX_W32
- SQLITE_MUTEX_NOOP
SQLITE_MUTEX_NOOP 实现是一组没有真正锁定的例程,适用于单线程应用程序。SQLITE_MUTEX_PTHREADS 和 SQLITE_MUTEX_W32 实现适用于 Unix 和 Windows。
如果使用定义的 SQLITE_MUTEX_APPDEF 预处理器宏编译 SQLite(使用 “-DSQLITE_MUTEX_APPDEF = 1”),则该库不包含互斥体实现。在这种情况下,应用程序必须在调用 sqlite3_initialize()或任何其他调用 sqlite3_initialize()的公共 sqlite3_ 函数之前,使用 sqlite3_config() 函数的 SQLITE_CONFIG_MUTEX 选项提供自定义互斥体实现。
sqlite3_mutex_alloc()例程分配一个新的互斥锁并返回一个指向它的指针。如果 sqlite3_mutex_alloc()例程无法分配所请求的互斥锁,则返回 NULL。sqlite3_mutex_alloc()的参数必须是下列其中一个整型常量:
- SQLITE_MUTEX_FAST
- SQLITE_MUTEX_RECURSIVE
- SQLITE_MUTEX_STATIC_MASTER
- SQLITE_MUTEX_STATIC_MEM
- SQLITE_MUTEX_STATIC_OPEN
- SQLITE_MUTEX_STATIC_PRNG
- SQLITE_MUTEX_STATIC_LRU
- SQLITE_MUTEX_STATIC_PMEM
- SQLITE_MUTEX_STATIC_APP1
- SQLITE_MUTEX_STATIC_APP2
- SQLITE_MUTEX_STATIC_APP3
- SQLITE_MUTEX_STATIC_VFS1
- SQLITE_MUTEX_STATIC_VFS2
- SQLITE_MUTEX_STATIC_VFS3
前两个常量(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()作为优化,所以这是可以接受的行为。
sqlite3_mutex_leave()例程退出先前由同一个线程输入的互斥锁。如果互斥量当前未被调用线程输入或当前未分配,则行为未定义。
如果 sqlite3_mutex_enter(),sqlite3_mutex_try() 或 sqlite3_mutex_leave()的参数是空指针,那么所有三个例程的行为都是 no-ops。