Qt 线程关闭

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();

 1 //线程处理函数
 2 public:
 3     void dis()
 4     {
 5         QMutex mutex;
 6         while(1)
 7         {
 8             mutex.lock();
 9             if(mtread.stop) break;
10             mutex.unlock();
11            //实际运行代码
12            //.....
13         }
14     }
15 //关闭线程函数
16     mtread.stop = true;
17     QThread->quit();
18     QThread->wait();

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

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

isInterruptionRequested()

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

 1 //线程处理函数
 2 public:
 3     void dis()
 4     {
 5         while(QThread::currentThread()->isInterruptionRequested())
 6         {
 7            
 8             //实际运行代码
 9             //.....
10         }
11     }
12 
13 //关闭线程函数
14     QThread->requestInterruption();
15     QThread->quit();
16     QThread->wait();
isInterruptionRequested() 往往配合QThread::currentThread()返回一个指向使用本函数线程的指针

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

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

1     QElapsedTimer et;  
2     et.start();  
3     while(et.elapsed()<300)  
4         QCoreApplication::processEvents();  
原文地址:https://www.cnblogs.com/ybqjymy/p/15074614.html