Qt 所有權問題導致多線程報錯


問題描述,把定時器放在單獨線程中使用,想提高精度。

結果報錯:

QObject::startTimer: Timers cannot be started from another thread。

這種報錯方式,以前剛用多線程時候遇見過。知道原因,所以更疑惑,百思不得其解。

在q羣問,集思廣益。

1.  多線程沒問題, 槽函數是在次線程運行的。

2. 通過在Worker::start函數中直接開啓定時器,不報錯,證明 定時器在主線程中。

3. 通過在槽函數中創建定時器,並啓動,不報錯。

4. 最終懷疑是因爲定時器不屬於Worker,所以worker移到次線程時,定時器還在主線程。將定時器父對象設爲Worker,驗證確實如此。


代碼:

#include <QtCore>
class Worker : public QObject
{
    Q_OBJECT
public:
    Worker(QObject *o=0);
signals:
    void start(int);
private slots:
    void handleStart(int d){ timer.start(d);}
    void onTimeout()
    {
        qDebug()<<"Worker::onTimeout get called from?: "<<QThread::currentThreadId();
    }
private:
    QTimer timer;
};

#include "main.moc"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qDebug()<<"From main thread: "<<QThread::currentThreadId();

    QThread t;

    Worker worker;

    worker.moveToThread(&t);

    t.start();
    emit worker.start(100);

    return a.exec();
}


Worker::Worker(QObject *o)
{
    connect(&timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
    connect(this, SIGNAL(start(int)), this, SLOT(handleStart(int)));
}

只需修改:

Worker::Worker(QObject *o):
    timer(this)
{
    connect(&timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
    connect(this, SIGNAL(start(int)), this, SLOT(handleStart(int)));
}


衆人拾柴火焰高。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章