Qt下的多线程的使用

Qt多线程的使用方法

Qt中关于多线程的类为QThread,有三种使用方法:一种方法是通过一个类继承QThread类,同时重写Thread::run()函数;第二种是直接实例化一个QThread,之后将继承自QObject的对象,通过QOjbect::moveToThread()搬到之前实例化的QThread执行;最后一种是通过

[static] template <typename Function, typename Args> QThread *QThread::create(Function &&f, Args &&... args)
[static] template <typename Function> QThread *QThread::create(Function &&f)

直接将一个函数搬到QThread中执行,有点类似于pthread_create()的方式。

Qt多线程注意的要点

Qt多线程前两种常用的方法在QT的帮助文档中都有查阅,读者可以自行去查看帮助文档。下面主要说几个使用QThread时,需要注意的几个知识点:

1.线程的一般分配

QT中一般使用主线程用于绘制界面和相应用户的事件,而用其它线程收发、处理数据,比如做上位机,可以使用主线程绘制界面,其它线程收发串口还有底层的数据,收到数据并处理之后,通过信号-槽机制,通知主线程根据数据更新界面。

2.关于Qt的信号和槽

[static] QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection)

Qt的Connect函数我们一般使用时只执行四个函数,而实际有五个函数,第五个函数说明了信号-槽在连接时的连接方式:

Qt::AutoConnection						0
Qt::DirectConnection 					1
Qt::QueuedConnection				2
Qt::BlockingQueuedConnection	3
Qt::UniqueConnection					0x80

默认参数为第一个,Qt::AutoConnection,它在信号-槽在同一线程下采用Qt::DirectConnection,在不同线程,采用Qt::QueuedConnection;而Qt::DirectConnection 适合信号和槽在同一线程,这样发出信号是,槽函数立即执行(实现原理可查看 设计模式 之 观察者模式);Qt::QueuedConnection 适合信号和槽在不同线程,槽函数在切回到其对应的线程时才会被执行;Qt::BlockingQueuedConnection则会堵塞当前线程,一直到槽函数执行完毕,适合信号和槽在多线程的情况,而信号和槽如果在同一个线程则会造成死锁,慎用!!。而Qt::UniqueConnection可以和其它几个参数进行或运算,防止信号槽被重复绑定,从而发出一个信号,对应的槽函数会被调用多次。
综合起来说,如果不确定第五个参数设置为哪一个,还是直接用默认参数把。

3.关于QThread停止

QThread停止主要涉及三个API,quit(),wait()和terminate(),其中quit()让QThread退出事件循环,wait()用于回收线程资源,类似于posix下的pthread_join()函数,这个函数是堵塞的;而terminate()是强制关停线程,比较暴力,一般不轻易使用。
通过停止线程的方法就是调用

QThread::quit();
QThread::wait();

在使用多线程的过程中,通常碰到这种情况,需要在多线程中执行一个死循环,那么如何停止这种线程呢?如果直接quit(),wait()是无法退出这种线程的。正确的做法是在循环之前设置一个标志位,比如这样:

class WorkThread
{
public:
	void work()
	void setRunning(bool running){ m_running= running;}
private:
	bool m_running;
}
void WorkThread::Work()
{
	while(running){
		...//线程逻辑
	}
}

在停止线程之前直接调用 setRunning(false),然后再调用quit(),wait()就可以优雅的停止线程;

4.线程停止之前

线程停止之后,尤其要注意调用 disconnect()函数,断开对应的信号和槽函数的连接。因为如果整个程序是单线程程序,一般不会调用disconnect(),因为信号和槽都在同一个线程中,保证了其声明周期一致;而多线程则无法保证声明周期一致,如果信号和槽分属不同的线程,在线程停止后,需要断开信号槽的连接,尤其是被杀死的线程含有槽函数时,不然会导致调用错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值