小。 速度很快。 可靠。 选择任意三个选项。
SQLite的自定义构建 或 将SQLite移植到新操作系统
1.0简介
对于大多数应用,建议的建筑方法 SQLite将使用 合并 代码 文件, 方形3.c ,及其相应的头文件 平方米3.h .sqlite3.c代码文件应编译并 在任何Unix、Windows系统上运行,无需任何更改 或特殊的编译器选项。 大多数应用程序可以简单地包括 sqlite3.c文件以及其他c代码文件 启动应用程序,将它们全部编译在一起,然后运行 和配置良好的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
Mutex很便宜,但不是免费的,所以性能会更好 当互斥锁被完全禁用时。 由此产生的库占用空间 也会小一点。 在编译时禁用互斥锁 是建议对有意义的应用程序进行的优化。
当使用SQLite作为共享库时,应用程序可以测试以查看 是否已使用 sqlite3_threadsafe() 应用程序编程接口。 链接到SQLite的应用程序 运行时和从多个线程使用SQLite可能应该检查 API以确保它们不会意外链接到 禁用互斥锁的SQLite库。 单螺纹 当然,无论是 不是SQLite被配置为线程安全,尽管它们会有点安全 在禁用互斥锁的情况下使用SQLite版本时速度会更快。
还可以在运行时使用 sqlite3_config() 接口。 要完全禁用所有静音, 应用程序可以调用:
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_mem状态 设置禁用机构 在SQLite中跟踪所有未完成内存的总大小 分配请求。 这样就不需要对每个调用进行互斥 到 sqlite3_malloc() 和 sqlite3_free() ,节省了大量资金 互斥操作数。 但禁用 内存统计机制是 sqlite3_内存使用() , sqlite3_memory_highwater() 、和 sqlite3_soft_heap_limit64() 接口停止工作。
SQLite在Unix和 SQLite需要递归互斥。 大多数现代pthread实现 支持递归互斥体,但并非所有互斥体都支持。对于不支持 支持递归互斥,建议应用程序运行 仅在单线程模式下。 如果这不可能,SQLite提供 基于 pthread的标准“快速”互斥体。 此替代方案 只要pthread_equal()是 atomic和处理器具有一致的数据缓存。 替代方案 递归互斥实现通过以下方式实现 编译器命令行开关:
-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() 接口。
Unix、Windows和OS/2上SQLite的默认构建包括 适用于目标平台的VFS。 其他SQLite构建 默认情况下,操作系统不包含VFS,但应用程序 可以在运行时注册一个或多个。
5.0将SQLite移植到新操作系统
为了将SQLite移植到新的操作系统-一个操作系统 默认情况下不支持系统-应用程序 必须提供。。。
一个工作的互斥子系统(但只有在它是多线程的情况下),
工作内存分配子系统(假设它缺少malloc() 在其标准库中),以及
一个有效的VFS实现。
所有这些都可以在单个辅助C代码文件中提供 然后链接到stock“sqlite3.c”代码文件以生成一个工作 目标操作系统的SQLite构建。 除了 替代互斥和内存分配子系统以及新的VFS, 辅助C代码文件应包含 以下两个例程:
“sqlite3.c”代码文件包含VFS的默认实现 和的 sqlite3_初始化() 和 sqlite3_shutdown() 功能 适用于Unix、Windows和OS/2。 防止在sqlite3.c时加载这些默认组件之一 编译时,需要添加以下编译时间 选项:
-DSQLITE_OS_OTHER=1
SQLite核心将调用 sqlite3_初始化() 提前。 辅助设备 C代码文件可以包含sqlite3_initialize()的实现 注册适当的VFS,也可能初始化替代 互斥系统(如果需要互斥)或进行任何内存分配 所需的子系统初始化。 SQLite内核从不调用 sqlite3_shutdown() 但它是 官方SQLite API,编译时不提供 -DSQLITE_OS_OTHER=1,因此辅助C代码文件可能应该提供 为了完整性。