2011-09-27 10 views
5

Sono turbato da come il modulo Sql funziona con l'applicazione multithread in Qt. http://doc.qt.io/qt-5/threads-modules.html#threads-and-the-sql-module indica chiaramente che "Una connessione può essere utilizzata solo all'interno del thread che lo ha creato".Modulo QSql e applicazione multithread

Tuttavia questo pezzo di codice che ho scritto opere:

#include <QCoreApplication> 
#include <QSqlQuery> 
#include <QtConcurrentRun> 

void req() 
{ 
    QSqlQuery q("INSERT INTO users (username) VALUES (\"test\")"); 
} 

void db() 
{ 
    QSqlDatabase _db; 

    _db = QSqlDatabase::addDatabase("QMYSQL"); 
    _db.setDatabaseName("dbname"); 
    _db.setHostName("host"); 
    _db.setUserName("username"); 
    _db.setPassword("password"); 
    if (_db.open()) 
    std::cout << "Ok" << std::endl; 
    else 
    std::cout << "Error" << std::endl; 
} 

int  main(int ac, char **av) 
{ 
    QCoreApplication app(ac, av); 
    QtConcurrent::run(db); 
    sleep(1); 
    QtConcurrent::run(req); 
    return app.exec(); 
} 

Il mio progetto applicazione richiede più thread di interagire con un database. Le filettature vengono generate e gestite da QtConcurrent :: run().

Quindi, dal momento che questa parte di codice funziona dovrei andare a prenderlo o mi imbatterò nei problemi ?

Qualsiasi aiuto, documentazione o spiegazione è benvenuto! Grazie.

risposta

6

Il codice sopra riportato va bene perché QSqlQuery creates its own QSqlDatabase. Sarebbe un problema se si fa riferimento a _db come creato da db(). Il lato negativo è che in realtà non è do nulla.

QSqlDatabase non è un QObject ma ha un driver che è un oggetto QObject e pertanto ha thread affinity.

Se la creazione di carichi di QSqlDatabases è proibitiva, creare worker threads che mantiene la propria connessione. Quindi invia query a questi thread anziché creare nuovi thread e quindi nuove connessioni.

+0

Cosa intendi per "Il lato negativo è che in realtà non fa nulla". ? La mia query viene eseguita e la voce inserita. Se capisco decentemente, QSqlQuery creerà il proprio QSqlDatabase usando la configurazione del database dal db creato da 'QSqlDatabase :: addDatabase()'? Ciò implica un sovraccarico (a causa di copie di oggetti o qualcosa del genere)? – Xaqq

+1

L'oggetto 'QSqlQuery' non sa nulla del' QSqlDatabase' che hai creato anche perché non stai usando il costruttore '' db' connected ''QSqlQuery :: QSqlQuery (QString &, QSqlDatabase)' (cioè non passi il pre -creato 'db' alla query). Il modo in cui istanziate la query significa che una nuova connessione DB separata verrà creata/abbattuta ogni volta che viene chiamato 'req()'. Quale è thread-safe, ma potenzialmente costoso. –

+0

Ho eseguito altri test e chiamando più QtConcurent :: run (req) sta causando il segfault del programma di test. modifica: sembra che l'instanciazione della query non sia thread-safe. – Xaqq