QT5线程关闭

稀土 2018-01-28

QT5线程关闭

QThread析构函数的说明:
请注意,删除一个QThread对象不会停止它管理的线程的执行。 删除正在运行的QThread(即isFinished()返回false)将导致程序崩溃。 在删除QThread之前等待finished()信号。

从Qt4.8起,可以释放运行刚刚结束的线程对象,通过连接finished()信号到QObject::deleteLater()。

QThread类

quit()

告诉线程的事件循环以return 0(成功)退出。 相当于调用QThread :: exit(0)。如果线程没有事件循环,这个函数什么也不做。

wait()

阻塞线程,直到满足以下任一条件:
与此QThread对象关联的线程已经完成执行(即从run()返回)。 如果线程完成,该函数将返回true。 如果线程尚未启动,它也返回true。
时间毫秒已经过去了。 如果时间是ULONG_MAX(默认值),那么等待永远不会超时(线程必须从run()返回)。 如果等待超时,此函数将返回false。

QMutex类

在QMutex的使用中,我们关注以下4个方法和2个属性:

1、QMutex ()//构造1个mutex 默认构造参数为非递归
2、lock ()//锁
3、tryLock ()//尝试着锁
4、unlock ()//释放锁

另外两个属性是:递归和非递归。如果这个mutex是递归的话,表明它可以被一个线程锁多次,也就是锁和解锁中再嵌套锁和解锁;非递归的话,就表明mutex只能被锁一次。

QMutexLocker类

相当于QMutex的简化,提供了简化了的互斥上的操作(也即简化了的加锁和解锁)。

使用详情可看帮助文档;

关闭线程

一.QMutex互斥锁 + bool成员变量。quit(),wait();

//线程处理函数
public:
    void dis()
    {
        QMutex mutex;
        while()
        {
            mutex.lock();
            if(mtread.stop) break;
            mutex.unlock();
           //实际运行代码
           //.....
        }
    }
//关闭线程函数
    mtread.stop = true;
    QThread->quit();
    QThread->wait();

以上还是存在mutex.unlock();没被调用的情况,可用QMutexLocker类优化

二.Qt5.2以后添加的新方法:requestInterruption() + isInterruptionRequested()

isInterruptionRequested()

如果一个应该停止的任务在此线程上运行,则返回true。 requestInterruption()可以请求中断。
这个功能可以用来使长时间运行的任务干净地中断。 建议在耗时长的运行函数中定期执行此操作。 注意不要太频繁地调用,以保持较低的开销。

//线程处理函数
public:
    void dis()
    {
        while(QThread::currentThread()->isInterruptionRequested())
        {
           
            //实际运行代码
            //.....
        }
    }

//关闭线程函数
    QThread->requestInterruption();
    QThread->quit();
    QThread->wait();
isInterruptionRequested() 往往配合QThread::currentThread()返回一个指向使用本函数线程的指针<br /><br /><strong>关于connect第五个参数,连接类型:</strong>
1)自动连接(AutoConnection),默认的连接方式,如果信号与槽,也就是发送者与接受者在同一线程,等同于直接连接;如果发送者与接受者处在不同线程,等同于队列连接。
2)直接连接(DirectConnection),当信号发射时,槽函数立即直接调用。无论槽函数所属对象在哪个线程,槽函数总在发送者所在线程执行。<br />3)队列连接(QueuedConnection),当控制权回到接受者所在线程的事件循环时,槽函数被调用。槽函数在接受者所在线程执行。
  • 阻塞队列(BlockingQueuedConnection)
  • 非阻塞队列(UniqueConnection

GUI界面假死的处理
在GUI程序中,主线程也叫GUI线程,因为它是唯一被允许执行GUI相关操作的线程。对于一些耗时的操作,如果放在主线程中,就是出现界面无法响应的问题。这种问题的解决一种方式是,把这些耗时操作放到次线程中,还有一种比较简单的方法:在处理耗时操作中频繁调用QApplication::processEvents()。这个函数告诉Qt去处理那些还没有被处理的各类事件,然后再把控制权返还给调用者。

QElapsedTimer et;  
    et.start();  
    while(et.elapsed()<)  
        QCoreApplication::processEvents();

相关推荐