Qt 定時器調用線程的用法

用處:

需要間隔一定的時間, 需要處理一些(繁重,耗時)的功能.

代碼塊1

MainWindow::MainWindow(QWidget *parent) :
        QObject(parent),
        num(0)
    {
       // 將 線程與定時器綁定.
        thread_class *object_class = new thread_class;
        QThread *thread = new QThread;
        object_class->moveToThread(thread);
        thread->start();
        // 定時器 觸發槽函數, 併發送信號 觸發線程(完全可以用定時器觸發 線程,)
        connect(&time,&QTimer::timeout,this,&slot_send);
        connect(this,SIGNAL(signal_send()),object_class,SLOT(dosomething()));
        time.start(1000);
    }
    MainWindow::~MainWindow()
    {
    }
    //  timeout 槽函數, 並打印住
    void MainWindow::slot_send()
    {
        if(num++ == 4)  time.stop();
        qDebug()<<"主線程:"<<QThread::currentThreadId();
        emit signal_send();
    }

代碼塊2

  thread_class::thread_class(QObject *obj):QObject(obj),num(0)
    {
    }
    void thread_class::dosomething()
    {
            qDebug()<<"子線程:"<<QThread::currentThreadId();
            QTimer time;
            time.setSingleShot(true);
            //模擬耗時的操作.
            QEventLoop loop;
            connect(&time,SIGNAL(timeout()),&loop,SLOT(quit()));
            time.start(5000);
            qDebug()<<"阻塞5S中...";
            loop.exec();
            qDebug()<<"阻塞完畢...";
    }

執行的結果:

主線程: 0x52d0
子線程: 0x5bfc
阻塞5S中…
主線程: 0x52d0
子線程: 0x5bfc
阻塞5S中…
主線程: 0x52d0
子線程: 0x5bfc
阻塞5S中…
主線程: 0x52d0
子線程: 0x5bfc
阻塞5S中…
主線程: 0x52d0
子線程: 0x5bfc
阻塞5S中…
阻塞完畢…
阻塞完畢…
阻塞完畢…
阻塞完畢…
阻塞完畢…

從中可以發現 定時調用線程, 並不會等待線程執行完, 只是按照定時間隔 觸發 線程,

潛在的bug:

** 當調用的線程還在執行的時候, 定時器又調用起一個線程, 如果執行中有共同的操作的變量, 會帶來資源同步的問題;
當時項目中,這塊有一個http請求後臺刷新文件的狀態, 狀態顯示完成後進行下載, 以至於下載的時候, 會出現重複下載的問題, 有的文件會下載幾遍.
**

解決辦法:

void thread_class::dosomething()
    {
            if (_block) return;
            else _block = true;
            qDebug()<<"子線程:"<<QThread::currentThreadId();
            QTimer time;
            time.setSingleShot(true);
            //模擬耗時的操作.
            QEventLoop loop;
            connect(&time,SIGNAL(timeout()),&loop,SLOT(quit()));
            time.start(5000);
            qDebug()<<"阻塞5S中...";
            loop.exec();
            qDebug()<<"阻塞完畢...";
            _block = false;
    }

測試代碼 :

https://github.com/heisai/time_thread_TestDemon.git

發佈了36 篇原創文章 · 獲贊 19 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章