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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章