ios - 进程间 SQLite 线程安全(在 iOS 上)

标签 ios sqlite thread-safety jailbreak

我正在尝试确定我对数据库的 sqlite 访问在 iOS 上是否是线程安全的。我正在编写一个非 App Store 应用程序(或者可能是一个启动守护程序),因此 Apple 的批准不是问题。有问题的数据库是内置的 sms.db ,所以可以肯定的是,操作系统也在访问这个数据库进行读写。我只希望能够安全地阅读它。

我读过 this about reading from multiple processes with sqlite :

Multiple processes can have the same database open at the same time. Multiple processes can be doing a SELECT at the same time. But only one process can be making changes to the database at any moment in time, however.

我知道线程安全可以从 sqlite 中编译出来,sqlite3_threadsafe() 可以用来测试它。在 iOS 5.0.1 上运行

int safe = sqlite3_threadsafe();

结果为 2。According to this ,这意味着互斥锁可用。但是,这并不一定意味着它在使用中。

我不是很清楚线程安全是在每个连接、每个数据库还是全局基础上动态启用的。

I have also read this .看起来 sqlite3_config() 可用于启用安全多线程,但当然,我无法控制,也无法了解操作系统本身如何使用此调用(是吗?)。如果我要在我的应用程序中再次进行该调用,它是否可以安全地读取数据库,或者它只会消除使用相同 sqlite3 的 我的应用程序 中多个线程的并发访问冲突 数据库句柄?

无论如何,我的问题是......

我能否安全地读取这个也由 iOS 访问的数据库,如果可以,如何读取?

最佳答案

我从未使用过 SQLite,但我花了相当多的时间阅读它的文档,因为我计划在将来使用它(而且文档很有趣)。我会说线程安全与多个进程是否可以同时访问同一个数据库文件无关。 SQLite,无论它处于何种线程模式,都会 lock the database file , 这样多个进程可以一次从数据库中读取,但只有一个进程可以写入。

Thread safety只影响你的进程如何使用 SQLite。没有任何线程安全,您只能从一个线程调用 SQLite 函数。但是它仍然应该,比如说,在写入之前获取一个 EXCLUSIVE 锁,这样其他进程就不能破坏数据库文件。如果您使用多线程,线程安全只是保护进程内存中的数据不被破坏。因此,我认为您无需担心另一个进程(在本例中为 iOS)正在使用 SQLite 数据库做什么。

编辑:澄清一下,任何时候写入数据库,包括普通的INSERT/UPDATE/DELETE,它会自动获取一个EXCLUSIVE锁,写入数据库,然后释放锁。 (它实际上需要一个 SHARED 锁,然后是一个 RESERVED 锁,然后是一个 PENDING 锁,然后是写入前的一个 EXCLUSIVE 锁。)默认情况下,如果数据库已经被锁定(比如来自另一个进程),那么 SQLite 将返回 SQLITE_BUSY 而无需等待.您可以调用sqlite3_busy_timeout()告诉它等待更长的时间。

关于ios - 进程间 SQLite 线程安全(在 iOS 上),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11058098/

相关文章:

mysql - sqlite加载数据infile语法错误

java - Statement.cancel() 及其线程安全保证

c++ - par_unseq 和 "vectorization-unsafe"函数

multithreading - 将多个嵌入式 javafx JFXPanel 管理到 swing tabbedpane 中

ios - 将 Objective-C malloc 转换为 Swift

ios - Django 休息框架日期时间字段格式

ios - 如何在父 View Controller 和 subview Controller 之间传输数据

sqlite - Cocoa 中的 SQLite3 磁盘 I/O 错误是什么

ios - Swift 5 & Alamofire 5 : GET method ERROR: Alamofire. AFError.URLRequestValidationFailureReason.bodyDataInGETRequest(22 字节)

sqlite - 将sqlite数据库与app和stringByAppendingPathComponent bundle 在一起