自己编译SQLite或将SQLite移植到新的操作系统(六)

65 篇文章 1 订阅
62 篇文章 4 订阅

 返回:SQLite—系列文章目录   

上一篇:SQLite中的动态内存分配(五)

下一篇:SQLite—系列文章目录   

1.0 引言

对于大多数应用程序,推荐的构建方法 SQLite是使用合并代码 文件 sqlite3.c 及其相应的头文件 sqlite3.h。sqlite3.c 代码文件应编译和 在任何 Unix、Windows 系统上运行,无需任何更改 或特殊的编译器选项。大多数应用程序可以简单地包括 sqlite3.c 文件以及其他 C 代码文件一起使 启动应用程序,将它们编译在一起,然后开始工作 和配置良好的 SQLite 版本。

大多数应用程序都可以很好地与 SQLite 一起使用 默认配置,没有特殊的编译时配置。 大多数开发人员应该能够完全忽略此文档 并且只需从合并中构建 SQLite而无需任何 特殊知识,无需采取任何特殊行动。

然而,高度调整和专业化 应用程序可能想要或需要替换一些 SQLite的内置系统接口与替代实现 更适合应用的需要。SQLite的设计 在编译时轻松重新配置以满足特定的 单个项目的需求。在编译时配置中 SQLite的选项如下:

  • 将内置互斥子系统替换为替代方案 实现。

  • 完全禁用所有互斥以用于单线程 应用。

  • 重新配置内存分配子系统以使用内存 分配器 其他 malloc() 实现从标准 图书馆。

  • 重新对齐内存分配子系统,使其永不调用 malloc() 满足所有内存请求 在启动时分配给 SQLite 的固定大小的内存缓冲区。

  • 将文件系统的接口替换为替代接口 设计。换言之,覆盖所有系统调用 SQLite使与磁盘通信具有完全不同的功能 系统调用集。

  • 覆盖其他操作系统接口,例如调用以获取 祖鲁语或当地时间。

一般来说,其中有三个独立的子系统 可以在编译时修改或覆盖的 SQLite。这 互斥子系统用于序列化对 SQLite 资源的访问,这些资源 在线程之间共享。使用内存分配子系统分配 SQLite对象和数据库所需的内存 缓存。最后,虚拟文件系统子系统是 用于在 SQLite 和底层之间提供可移植接口 操作系统,尤其是文件系统。我们称这三个 子系统 SQLite 的“接口”子系统。

我们强调,大多数应用程序都由 SQLite接口子系统的内置默认实现。 鼓励开发人员使用 尽可能默认的内置实现 并在没有任何特殊编译时选项或参数的情况下构建 SQLite。 但是,一些高度专业化的应用程序可能会从以下方面受益 替换或修改这些内置 SQLite 中的一个或多个 接口子系统。 或者,如果SQLite用于 Unix(Linux 或 Mac OS X)、Windows(Win32 或 WinCE)或 OS/2,然后没有 内置到SQLite中的接口子系统将起作用 应用程序需要提供替代实现 适用于目标平台。

2.0 配置或替换互斥子系统

在多线程环境中,SQLite 使用互斥锁进行序列化访问共享资源。 互斥子系统仅对访问的应用程序是必需的来自多个线程的 SQLite。对于单线程应用程序,或者仅从单个线程调用SQLite 的应用程序,互斥锁子系统可以通过以下命令重新编译来完全禁用 选择:

-DSQLITE_THREADSAFE=0

互斥锁很低占用资源,但不是还是会消耗一点资源的,所以当互斥锁被完全禁用时性能会更好。生成的库占用空间也会小一点。在编译时禁用互斥锁是针对有意义的应用程序的建议优化。

当使用 SQLite 作为共享库时,应用程序可以测试以查看 是否已使用 sqlite3_threadsafe() API 禁用互斥锁。链接到 SQLite 的应用程序 运行时并从多个线程使用 SQLite 可能应该检查这一点 API 来确保它们不会意外地链接到 禁用了互斥锁的 SQLite 库。单线程 当然,无论应用程序是否正常工作,应用程序都将正常工作。 不是 SQLite 被配置为线程安全,尽管它们会有点 使用禁用互斥锁的 SQLite 版本时速度更快。

也可以在运行时使用 sqlite3_config() 接口禁用 SQLite 互斥锁。要完全禁用所有互斥, 应用程序可以调用:

sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);

在运行时禁用互斥锁不如禁用互斥锁有效 在编译时,因为 SQLite 仍然必须对布尔变量进行测试 查看互斥锁在互斥锁的每个点是启用还是禁用互斥锁 可能是必需的。但是仍然有性能优势 在运行时禁用互斥锁。

对于多线程应用程序,它们会注意如何 管理线程,SQLite支持替代运行时配置 这是在不使用任何互斥锁和默认情况之间的中间位置 互斥视线中的一切。这种中间互斥锁对齐可以 按以下方式建立:

sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
sqlite3_config(SQLITE_CONFIG_MEMSTATUS, 0);

这里有两个单独的配置更改,可以一起使用,也可以单独使用。SQLITE_CONFIG_MULTITHREAD设置禁用 序列化对数据库连接对象和预准备语句对象的访问。使用此设置时,应用程序 可以从多个线程免费使用 SQLite,但必须确保 没有两个线程尝试同时访问相同的数据库连接或与同一数据库连接关联的任何预准备语句。两个线程可以使用 SQLite 同时,但它们必须使用单独的数据库连接。 第二个SQLITE_CONFIG_MEMSTATUS设置禁用该机制 在SQLite中跟踪所有未完成内存的总大小 分配请求。这样就不需要对每个调用进行互斥处理 到 sqlite3_malloc() 和 sqlite3_free(),这节省了巨大的 互斥操作数。但是禁用 内存统计机制是 sqlite3_memory_used()sqlite3_memory_highwater() 和 sqlite3_soft_heap_limit64() 接口停止工作。

SQLite 使用 pthreads 作为其在 Unix 上的互斥锁实现,并且 SQLite 需要递归互斥锁。最现代的 pthread 实现 支持递归互斥锁,但并非所有互斥锁都支持。对于不这样做的系统 支持递归互斥锁,建议应用运行 仅在单线程模式下。如果这是不可能的,SQLite提供 另一种递归互斥体实现,建立在 pthread 的标准“快速”互斥锁。此替代方案 只要 pthread_equal() 是 原子和处理器具有连贯的数据缓存。替代方案 递归互斥锁实现由以下方式启用 编译器命令行开关:

-DSQLITE_HOMEGROWN_RECURSIVE_MUTEX=1

将SQLite移植到新的操作系统时,通常是必要的 将内置互斥子系统完全替换为替代方案围绕新操作系统的互斥原语构建。这通过使用以下选项编译 SQLite 来完成:

-DSQLITE_MUTEX_APPDEF=1

当使用 SQLITE_MUTEX_APPDEF=1 选项编译 SQLite 时,它完全省略了其互斥基元函数的实现。但是SQLite 库仍会在必要时尝试调用这些函数,因此应用程序本身必须实现互斥基元函数并将它们链接在一起使用 SQLite。

3.0 配置或替换内存分配子系统

默认情况下,SQLite 获取对象所需的内存和从标准库的 malloc()/free()实现中缓存。 实验性内存分配器的工作也在进行中满足来自单个固定内存缓冲区的所有内存请求在应用程序启动时添加到 SQLite。有关这些的其他信息实验性内存分配器将在将来的修订版中提供的本文档。

SQLite支持应用程序指定替代方案的能力 内存分配器 在运行时sqlite3_mem_methods,通过使用指向 替代实现,然后注册新的替代 使用 sqlite3_config() 接口实现。 例如:

sqlite3_config(SQLITE_CONFIG_MALLOC, &my_malloc_implementation);

SQLite复制 sqlite3_mem_methods 象的内容 因此,可以在 sqlite3_config()调用返回后修改对象。

4.0 添加新的虚拟文件系统

自 3.5.0 版 (2007-09-04)起, SQLite支持称为虚拟文件系统或“VFS”的接口。 这个对象有点命名错误,因为它 实际上是整个底层操作系统的接口,而不是 只是文件系统。

有趣的功能之一 VFS 接口是SQLite可以在同时。每个数据库连接都必须为其选择一个VFS 使用 sqlite3_open_v2() 首次打开连接时使用。 但是,如果一个进程包含多个数据库连接,则每个数据库连接都可以选择不同的VFS。可以在运行时使用 sqlite3_vfs_register() 接口添加 VFS。

Unix、Windows 和 OS/2 上 SQLite 的默认版本包括 适用于目标平台的 VFS。为其他构建的 SQLite 默认情况下,操作系统不包含 VFS,但应用程序 可以在运行时注册一个或多个。

5.0 将SQLite移植到新的操作系统

为了将SQLite移植到新的操作系统 - 操作 默认情况下不支持系统 - 应用程序 必须提供...

  • 一个有效的互斥子系统(但前提是它是多线程的),
  • 工作内存分配子系统(假设它缺少 malloc() 在其标准库中),以及
  • 一个有效的 VFS 实现。

所有这些东西都可以在一个辅助C代码文件中提供然后链接到库存的“sqlite3.c”代码文件以生成一个有效的目标操作系统的 SQLite 构建。除了 替代互斥锁和内存分配子系统以及新的 VFS, 辅助 C 代码文件应包含 以下两个例程:

“sqlite3.c”代码文件包含 VFS 的默认实现 以及 sqlite3_initialize() 和 sqlite3_shutdown()函数适用于 Unix、Windows和OS/2。 防止在sqlite3.c 时加载这些默认组件之一 编译后,需要添加以下编译时 选择:

-DSQLITE_OS_OTHER=1

SQLite 核心将提前调用 sqlite3_initialize()。辅助 C 代码文件可以包含 sqlite3_initialize()的实现注册适当的 VFS,并且可能还初始化替代方案 互斥系统(如果需要互斥锁)或进行任何内存分配所需的子系统初始化。 SQLite 核心从不调用 sqlite3_shutdown(),但它是 官方 SQLite API,编译时未另行提供 -DSQLITE_OS_OTHER=1,所以辅助 C 代码文件可能应该提供 它是为了完整性。

  • 25
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

界忆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值