2 Stimmen

SQLite: Persistieren von Datei-Handles im WAL-Modus

Ich habe ein C++-Programm, in dem ich mehrere Threads habe, die in meine SQLite-Tabellen (WAL-Modus ist aktiviert) einer einzigen Datenbank schreiben. Jeder Thread erstellt ein SQLite-Handle, führt ein sqlite3_open() aus, schreibt in die Tabellen (es wird in einer Transaktion geschrieben) und führt dann ein sqlite3_close() aus, und dann werden die SQLite-Handles gelöscht. Dann stirbt der Thread.

Selbst wenn alle Threads absterben, sind die SQLite-Handles noch offen. Warum werden die SQLite-Handles nicht geschlossen? Was übersehe ich hier?

Mein C++-Programm läuft auf einem CentOS 5.5.

[Bearbeiten] Hier ist mein Beispielprogramm mit 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;
}

4voto

omggs Punkte 1143

Ich habe das SQLite-Team kontaktiert: Hier ist ihre Antwort-

Wenn Sie eine Verbindung schließen (In WAL Modus), SQLite prüft, ob eine andere Verbindung im Prozess eine eine POSIX-Sperre auf die zu schließende Datenbankdatei hält. Wenn ja, verschiebt es das Schließen des Dateihandles, bis die andere Verbindung ihre POSIX-Sperre aufhebt (der Dateideskriptor wird wiederverwendet, wenn eine weitere Verbindung zur gleichen Datei geöffnet wird, aber ansonsten wird einfach wartet er, bis er sicher geschlossen werden kann).

Die Schlussfolgerung ist: Solange die Verbindung nicht von der Funktion main() geschlossen wird werden die Handles, die von den anderen Threads geöffnet wurden, nicht geschlossen!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X