2

単一のデータベースのSQLiteテーブル(WALモードが有効)に複数のスレッドを書き込んでいるC++プログラムがあります。各スレッドはSQLiteハンドルを作成し、sqlite3_open()を実行し、テーブルに書き込み(トランザクション内に書き込みがあります)、次にsqlite3_close()を実行し、SQLiteハンドルが削除されます。その後、スレッドが終了します。

すべてのスレッドが停止した後でも、SQLiteハンドルは開いたままです。SQLiteハンドルが閉じられないのはなぜですか?ここで何が欠けていますか?

私のC++プログラムはCentOS5.5で実行されています。

[編集]これが私のサンプルプログラムですpthread

void threadFunction(void* pArg) {
    sqlite3 *handle;
    sqlite3_open("a.cm", &handle);    
    printf("Worker thread - Opened \n");
    sleep(10);    
    int r = sqlite3_close(handle);
    printf("Ret: %d\n", r);
    printf("Worker thread - Closed \n");
}

int main() {
    int i(0);
    pthread_t thread1, thread2;
    printf("Creating a worker thread\n");
    printf("SQLite libversion: %s\n", sqlite3_libversion());
    sqlite3 *handle;
    sqlite3_open("a.cm", &handle);    
    sqlite3_exec(handle, "pragma journal_mode = WAL", NULL, NULL, NULL);    
    printf("Main thread - Opened \n");

    pthread_create(&thread1, NULL, threadFunction, NULL);
    pthread_create(&thread2, NULL, threadFunction, NULL);

    pthread_join( thread1, NULL);
    pthread_join( thread2, NULL);
    sleep(200);
    sqlite3_close(handle);
    printf("Main thread - close \n");
    return 0;
}
4

1 に答える 1

4

SQLiteチームに連絡しました: これが彼らの返事です-

1 つの接続を (In モードで) 閉じるとWAL、SQLite は、プロセス内の他の接続が閉じているデータベース ファイルの POSIX ロックを保持しているかどうかをチェックします。その場合、他の接続がその POSIX ロックをドロップするまで、ファイルハンドルを閉じるのを延期します (同じファイルへの別の接続が開かれている場合、ファイル記述子は再利用されますが、それ以外の場合は、安全に閉じられるまで待機します)。 .

結論は次のとおりです。接続が main() 関数から閉じられるまで、他のスレッドから開かれたハンドルは閉じられません!

于 2012-04-30T04:54:12.557 に答える