2011-09-27 22 views
5

Me preocupa cómo funciona el módulo Sql con la aplicación multiproceso en Qt. http://doc.qt.io/qt-5/threads-modules.html#threads-and-the-sql-module indica claramente que "Una conexión solo se puede utilizar desde el hilo que la creó".Módulo QSql y aplicación multiproceso

Sin embargo, este trozo de código que he escrito obras:

#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(); 
} 

Mi diseño de la aplicación requiere de múltiples hilos para interactuar con una base de datos. Thoses threads son generados y administrados por QtConcurrent :: run().

Entonces, dado que este código funciona, ¿debería hacerlo o me encontraré con problemas al hacerlo?

¡Toda ayuda, documentación o explicación es bienvenida! Gracias.

Respuesta

6

El código anterior está bien porque QSqlQuery creates its own QSqlDatabase. Sería un problema si hace referencia a _db como creado por db(). El lado negativo es que en realidad no hace nada.

QSqlDatabase no es un objeto QObject pero tiene un driver que es un objeto QObject y por lo tanto tiene thread affinity.

Si la creación de cargas de QSqlDatabases es prohibitiva, cree worker threads que mantenga su propia conexión. A continuación, envíe consultas a estos hilos en lugar de crear nuevos hilos y, por lo tanto, nuevas conexiones.

+0

¿Qué quiere decir con "El inconveniente es que en realidad no hace nada". ? Mi consulta se ejecuta y la entrada se inserta. Si entiendo decentemente, QSqlQuery creará su propia QSqlDatabase usando la configuración de la base de datos desde el archivo db creado por 'QSqlDatabase :: addDatabase()'? ¿Eso implica una gran cantidad de gastos generales (debido a copias de objetos o algo así)? – Xaqq

+1

Su objeto 'QSqlQuery' no sabe nada acerca de' QSqlDatabase' que también creó porque no está usando el constructor '' db' conectado 'QSqlQuery :: QSqlQuery (QString &, QSqlDatabase)' (es decir, no pasa el pre -created 'db' a la consulta). La forma en que crea la instancia de la consulta significa que se creará/destruirá una nueva conexión de base de datos separada cada vez que se llame a 'req()'. Que es seguro para subprocesos, pero potencialmente costoso. –

+0

Hice algunas pruebas más, y llamar a QtConcurent :: run (req) múltiple hace que el programa de prueba falte por segmentación. editar: parece que la instanciación de la consulta no es segura para subprocesos. – Xaqq

Cuestiones relacionadas