Qt:使用一个连接从多个线程写入数据库

时间:2015-02-18 14:30:02

标签: c++ multithreading qt qsqldatabase

问题在于:我们说有很多线程(> 1000)通过某些协议接收数据,我想在数据库(sql server)中写入这些数据。

对于数据库连接,我们使用QSqlDatabase。根据{{​​1}}的文档:

  

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

考虑到我们无法创建1000个连接(这可能会导致性能问题),这里有哪些选项?

我们想到的是为数据库着作处理创建一个单独的线程。

但是如何在后台运行这个线程并等待来自数据接收线程的信号?在这种情况下可以使用哪些其他方法?

2 个答案:

答案 0 :(得分:1)

我使用数据库连接作为全局记录器,因此您可以根据自己的需要进行调整。 骨架看起来像:

    //Logger.h
class Logger : public QObject
{
    Q_OBJECT
    ...
public:
    void log(const QString& msg):

private:
    LoggerWorker* w;
    QThread t;
}


// Logger.cpp
Logger::Logger(QObject* p)
:QObject(p)
{
    w = new LoggerWorker;
    w->moveToThread(&t);
    connect(&t, SIGNAL(started()), w, SLOT(init()));
    t.start();
}

...
void 
Logger::log(const QString& msg)
{
    QMetaObject::invokeMethod(w, "log", Q_ARG(QString, msg));
}

// LoggerWorker.h
class LoggerWorker : public QObject
{
    Q_OBJECT
    ...
public slots:
    void init()
    {
        // create database and connect to it
    }
    void log(const QString& msg)
    {
        // insert to database
    }

private:
    QSqlDatabase db;
}

注意:上面的代码可能包含坚果和错误

欢呼声

答案 1 :(得分:1)

最好的选择是拥有一个用于处理数据库的类,它位于单独的线程中。您可以在相关的插槽中执行所有与数据库相关的操作。不同的线程可以通过将它们的信号连接到它的插槽来与类的对象交互。由于发射器和接收器存在于不同的线程中,因此您将具有排队的连接类型。因此,从不同线程发出的不同信号将在数据库类中排队以进行处理。