从多个线程使用QSqlQuery

Gus*_*avo 1 qt multithreading qtsql c++11

我有许多正在运行的C ++ 11线程,它们都需要在某个时间访问数据库。在主要方面,我会初始化数据库连接并打开数据库。Qt文档说查询不是线程安全的,因此在线程内部存在QSqlQuery之前,我将使用全局互斥锁。

这行得通,但是否可以保证正常工作,或者我有时会遇到问题?

Fel*_*lix 6

看看文档告诉我们,

连接只能在创建它的线程中使用。不支持在线程之间移动连接或从其他线程创建查询。

因此,您确实确实需要每个线程一个连接。我通过基于线程生成动态名称来解决此问题:

auto name = "my_db_" + QString::number((quint64)QThread::currentThread(), 16);
if(QSqlDatabase::contains(name))
    return QSqlDatabase::database(name);
else {
    auto db = QSqlDatabase::addDatabase( "QSQLITE", name);
    // open the database, setup tables, etc.
    return db;
}
Run Code Online (Sandbox Code Playgroud)

如果您使用非Qt管理的线程,请使用来QThreadStorage为每个线程生成名称:

// must be static, to be the same for all threads
static QThreadStorage<QString> storage;

QString name;
if(storage.hasLocalData())
    name = storage.localData();
else {
    //simple way to get a random name
    name = "my_db_" + QUuid::createUuid().toString();
    storage.setLocalData(name);
}
Run Code Online (Sandbox Code Playgroud)

重要提示: Sqlite可能能够或可能不能处理多线程。请参阅https://sqlite.org/threadsafe.html。据我所知,嵌入到Qt中的sqlite是线程安全的,这就是默认设置,我在源代码中找不到任何禁用它的标志。但是,如果您使用其他sqlite版本,请确保它确实支持线程。