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_MUTEX_APPDEF预处理程序宏(“ -DSQLITE_MUTEX_APPDEF = 1”)编译SQLite,则该库不包含互斥量实现。在这种情况下,应用程序必须在调用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)使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()的参数是NULL指针,则所有三个例程的行为都等同于no-ops。