10

データベースへの sqlite アクセスが iOS でスレッドセーフかどうかを判断しようとしています。私は App Store 以外のアプリ (または起動デーモン) を作成しているので、Apple の承認は問題になりません。問題のデータベースは組み込みのsms.dbであるため、OS も読み取りと書き込みのためにこのデータベースにアクセスしていることは確かです。私はそれを安全に読むことができるようにしたいだけです。

sqlite を使用した複数のプロセスからの読み取りについて、これを読みました。

複数のプロセスが同時に同じデータベースを開くことができます。複数のプロセスが同時に SELECT を実行できます。ただし、いつでもデータベースに変更を加えることができるプロセスは 1 つだけです。

スレッドセーフは sqlite からコンパイルできることを理解しており、それsqlite3_threadsafe()を使用してこれをテストできます。これを iOS 5.0.1 で実行する

int safe = sqlite3_threadsafe();

結果は 2 になります。これによると、ミューテックス ロックが使用可能であることを意味します。しかし、それは必ずしもそれが使用されているという意味ではありません。

スレッドセーフが接続ごと、データベースごと、またはグローバルベースで動的に有効化されているかどうかは完全にはわかりません。

私もこれを読みました。安全なマルチスレッドを有効にするために使用できるように見えますsqlite3_config()が、もちろん、OS 自体がこの呼び出しをどのように使用したかを制御または可視化することはできません (そうですか?)。アプリでその呼び出しを再度行った場合、データベースを安全に読み取ることができますか?それとも、同じデータベース ハンドルを使用するアプリ内の複数のスレッドに対する同時アクセスの競合のみを解決するでしょうか?sqlite3

とにかく、私の質問は...

iOS からもアクセスされるこのデータベースを安全に読み取ることができますか?

4

2 に答える 2

12

私はSQLiteを使用したことがありませんが、将来使用する予定があるため、ドキュメントを読むのにかなりの時間を費やしました(ドキュメントは興味深いものです)。スレッドセーフは、複数のプロセスが同じデータベースファイルに一度にアクセスできるかどうかとは無関係だと思います。SQLiteは、どのスレッドモードにあるかに関係なく、データベースファイルをロックするため、複数のプロセスがデータベースから一度に読み取ることができますが、書き込むことができるのは1つだけです。

スレッドセーフは、プロセスがSQLiteを使用する方法にのみ影響します。スレッドセーフがなければ、1つのスレッドからのみSQLite関数を呼び出すことができます。ただし、他のプロセスがデータベースファイルを破損しないように、書き込み前にEXCLUSIVEロックを取得する必要があります。スレッドセーフは、複数のスレッドを使用する場合に、プロセスのメモリ内のデータが破損するのを防ぐだけです。したがって、別のプロセス(この場合はiOS)がSQLiteデータベースで何をしているのかを心配する必要はないと思います。

編集:明確にするために、プレーンINSERT//を含めてデータベースに書き込むときはいつでも、自動的にEXCLUSIVEロックを取得し、データベースに書き込んでから、ロックを解放します。(実際には、SHAREDロック、RESERVEDロック、PENDINGロック、書き込み前のEXCLUSIVEロックの順になります。)デフォルトでは、データベースがすでにロックされている場合(たとえば、別のプロセスから)、SQLiteは待機せずにSQLITE_BUSYを返します。 。あなたはそれをもっと長く待つように言うために電話することができます。UPDATEDELETEsqlite3_busy_timeout()

于 2012-07-07T01:15:56.570 に答える
2

これはあなたにとってニュースではないと思いますが、いくつかの考えがあります:

マルチスレッド(シリアル化またはマルチスレッド)を有効にするという点で、一般的な助言は、並べ替えを有効にするために呼び出すことができるということです(ただし、ドキュメントsqlite3_config()で提案されているように、またはSO here で説明されているように、最初にシャットダウンを行う必要がある場合があります)。あなたが望むマルチスレッドの。ただし、iOS が sqlite やこのデータベースに要求しているアクセスの種類を制御できない場合、ここでは有用性が低下する可能性があります。

したがって、学術的な観点からは、このシステム データベースを読み取るのは安全ではないと考えていたでしょう (OS が何をしているのかについて保証がないため)。しかし、iOS がデフォルト モードを使用してデータベースを開いていても驚かないので、より実用的な観点からは問題ないでしょう。

明らかに、1 つのアプリ内でのマルチスレッド アクセスを懸念するほとんどのユーザーにとって最善のアドバイスは、sqlite3_config()愚かなことを回避し、独自の GCD シリアル キューを介して調整されたアクセスを確保することです (つまり、すべてのデータベース インタラクションが通過する専用のキューを用意します)。を通じて、マルチスレッドの問題を完全に排除します)。残念ながら、iOS 自体とのデータベースの対話を調整しようとしているため、ここではオプションではありません。

于 2012-06-16T17:45:59.380 に答える