2011-09-27 2 views
5

Sql 모듈이 Qt에서 다중 스레드 응용 프로그램과 함께 작동하는 방식에 문제가 있습니다. http://doc.qt.io/qt-5/threads-modules.html#threads-and-the-sql-module은 "연결을 만들 수있는 스레드 내에서만 연결을 사용할 수 있음"이라는 명확한 설명을 으로 명시합니다.QSql 모듈과 멀티 스레드 응용 프로그램

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

내 응용 프로그램 설계는 데이터베이스와 상호 작용하는 여러 스레드가 필요합니다

그러나이 코드 조각이 나는 작품을 썼다. 스레드 은 QtConcurrent :: run()에 의해 생성되고 관리됩니다.

코드 조각이 작동해야하기 때문에 또는 그 일을 수행하면 문제가 발생합니까?

도움, 문서 또는 설명을 환영합니다! 감사합니다.

답변

6

위의 코드는 QSqlQuery creates its own QSqlDatabase이므로 문제가 없습니다. _dbdb()으로 작성한 것으로 언급하면 ​​문제가됩니다. 아래쪽은 실제로는 을 수행하지 않는다는 것입니다.은 무엇이든합니다.

QSqlDatabase는 QObject가 아니지만 QObject 인 driver이므로 thread affinity입니다.

로드가 많은 QSqlDatabases를 만드는 것이 금지 된 경우 자체 연결을 유지하는 worker threads을 작성하십시오. 그런 다음 새 스레드와 새로운 연결을 작성하는 대신 이러한 스레드에 조회를 보내십시오.

+0

"아래쪽은 실제로 아무 것도하지 않는다는 것입니다." ? 내 쿼리가 실행되고 항목이 삽입되었습니다. 필자가 이해한다면 QSqlQuery는'QSqlDatabase :: addDatabase()'에 의해 생성 된 데이터베이스의 데이터베이스 구성을 사용하여 자체 QSqlDatabase를 생성 할 것인가? 그것은 많은 오버 헤드를 의미합니까 (객체의 사본 또는 무언가 때문에)? – Xaqq

+1

''db' 연결된 "생성자'QSqlQuery :: QSqlQuery (QString &, QSqlDatabase)'를 사용하지 않기 때문에'QSqlQuery' 객체는 여러분이 생성 한'QSqlDatabase'에 대해서 아무것도 모릅니다. (즉, 쿼리에'db '를 생성). 쿼리를 인스턴스화하는 방법은'req()'가 호출 될 때마다 새로운 별도의 DB 연결이 생성/분리된다는 것을 의미합니다. 쓰레드 안전하지만 잠재적으로 비싸다. –

+0

나는 더 많은 테스트를했는데 여러 QtConcurent :: run (req)을 호출하면 테스트 프로그램이 segfault를 일으켰습니다. 편집 : 그것은 쿼리 instanciation 스레드 안전하지 않은 것으로 보인다. – Xaqq